Semana 7¶
Sesión 1 y 2¶
En esta sesión realizaremos la retroalimentación del parcial número 2.
Un posible modelo de la solución es este:
Y una posible implementación del modelo es este otro modelo en C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | void setup() {
Serial.begin(115200);
}
void taskCom() {
enum class state_t {WAIT_INIT, WAIT_PACKET, WAIT_ACK};
static state_t state = state_t::WAIT_INIT;
static uint8_t bufferRx[20] = {0};
static uint8_t dataCounter = 0;
static uint32_t timerOld;
static uint8_t bufferTx[20];
switch (state) {
case state_t::WAIT_INIT:
if (Serial.available()) {
if (Serial.read() == 0x3E) {
Serial.write(0x4A);
dataCounter = 0;
timerOld = millis();
state = state_t::WAIT_PACKET;
}
}
break;
case state_t::WAIT_PACKET:
if ( (millis() - timerOld) > 1000 ) {
Serial.write(0x3D);
state = state_t::WAIT_INIT;
}
else if (Serial.available()) {
uint8_t dataRx = Serial.read();
if (dataCounter >= 20) {
Serial.write(0x3F);
dataCounter = 0;
timerOld = millis();
state = state_t::WAIT_PACKET;
}
else {
bufferRx[dataCounter] = dataRx;
dataCounter++;
// is the packet completed?
if (bufferRx[0] == dataCounter - 1) {
// Check received data
uint8_t calcChecksum = 0;
for (uint8_t i = 1; i <= dataCounter - 1; i++) {
calcChecksum = calcChecksum ^ bufferRx[i - 1];
}
if (calcChecksum == bufferRx[dataCounter - 1]) {
bufferTx[0] = dataCounter - 3; //Length
calcChecksum = bufferTx[0];
// Calculate Tx checksum
for (uint8_t i = 4; i <= dataCounter - 1; i++) {
bufferTx[i - 3] = bufferRx[i - 1];
calcChecksum = calcChecksum ^ bufferRx[i - 1];
}
bufferTx[dataCounter - 3] = calcChecksum;
Serial.write(0x4A);
Serial.write(bufferTx, dataCounter - 2);
timerOld = millis();
state = state_t::WAIT_ACK;
}
else {
Serial.write(0x3F);
dataCounter = 0;
timerOld = millis();
state = state_t::WAIT_PACKET;
}
}
}
}
break;
case state_t::WAIT_ACK:
if ( (millis() - timerOld) > 1000 ) {
timerOld = millis();
Serial.write(bufferTx, dataCounter - 2);
} else if (Serial.available()) {
if (Serial.read() == 0x4A) {
state = state_t::WAIT_INIT;
}
}
break;
}
}
void loop() {
taskCom();
}
|
Un ejemplo de una escenario de prueba: