Index: webserver/example/EnergyMeters/Source/EnergyMeters/SolarCountUART.c =================================================================== --- webserver/example/EnergyMeters/Source/EnergyMeters/SolarCountUART.c (revision 58) +++ webserver/example/EnergyMeters/Source/EnergyMeters/SolarCountUART.c (revision 66) @@ -13,4 +13,7 @@ static void advanceHistoryArray(void); + +void crc16_ccitt(char ser_data); + #define solarSTACK_SIZE configMINIMAL_STACK_SIZE+200 @@ -29,4 +32,9 @@ +unsigned long correctVoltWattRx = 0; /* counter of correctly received wattage/voltage packets */ +unsigned long failedVoltWattRx = 0; /* counter of incorrectly received wattage/voltage packets */ + + +static unsigned short staticCRC; @@ -503,8 +511,25 @@ if ((currentChannel >= 0) && (currentChannel < 6)) { - portENTER_CRITICAL(); - chanVolt[currentChannel] = rxUART3[11]; - chanWatt[currentChannel] = (int)(rxUART3[7]) | (((int)(rxUART3[8])) << 8) /* index 7: LSB, index 8: MSB */; - portEXIT_CRITICAL(); + + if (checkRxTwoByteCheckSum() == 1) + { + /* checksum correct */ + portENTER_CRITICAL(); + chanVolt[currentChannel] = rxUART3[11]; + chanWatt[currentChannel] = (int)(rxUART3[7]) | (((int)(rxUART3[8])) << 8) /* index 7: LSB, index 8: MSB */; + correctVoltWattRx++; + portEXIT_CRITICAL(); + } + else + { + /* checksum incorrect */ + portENTER_CRITICAL(); + /* mark values as invalid */ + //chanVolt[currentChannel] = 1; + chanWatt[currentChannel] = SOLAR_FSM_INVALID_VALUE; + failedVoltWattRx++; + portEXIT_CRITICAL(); + } + } /* if */ @@ -750,2 +775,94 @@ } + + + +portCHAR checkRxOneByteCheckSum(void) +{ + portCHAR retVal; /* return value */ + +// "\xf0\xb0\x0a\x00\xa0\x00\x87\x00\x00\x00\xec\x00\xf2\ + + int x; + + unsigned long crcLONG = 0; + unsigned char crcCHAR; + unsigned char crcCHARinv; + unsigned char carry = 0; + + /* use bytes 1 to 13 for the checksum */ + for (x = 1; x <= 13; x++) + { + + /* overflow? */ + // if (((portSHORT)crc + (portSHORT)(rxUART3[x])) > 0xFF) + // { + // carry++; + // } + + crcLONG = (crcLONG + rxUART3[x]); /* add and truncate to 8 bit */ + } + + carry = (unsigned char)(((crcLONG & 0xFF00) >> 8)); + + crcCHAR = (unsigned char)(crcLONG & 0xFF); + + crcCHAR = (unsigned char)(crcCHAR + carry); + crcCHARinv = (unsigned char)(~crcCHAR); + + + if (crcCHARinv == rxUART3[14]) + { + retVal = 1; /* checksum OK, data is valid */ + } + else + { + retVal = 0; /* checksum error, data is invalid */ + } + return retVal; +} /* checkRxOneByteCheckSum */ + + +portCHAR checkRxTwoByteCheckSum(void) +{ + unsigned short cmpValue; + portCHAR retVal; /* return value */ + portCHAR x; + + staticCRC = 0xFFFF; /* init 16 bit checksum CRC start value */ + + /* use bytes 1 to 13 for the checksum */ + for (x = 1; x <= 12; x++) + { + + crc16_ccitt(rxUART3[x]); + } + + + + cmpValue = ((((unsigned short)rxUART3[14])<<8) | rxUART3[13]); + if (cmpValue == (staticCRC & 0xFFFF)) + { + retVal = 1; /* checksum OK, data is valid */ + } + else + { + retVal = 0; /* checksum error, data is invalid */ + } + return retVal; + +} /* portCHAR checkRxTwoByteCheckSum() */ + + + + +void crc16_ccitt(char ser_data) +{ + staticCRC = (unsigned char)(staticCRC >> 8) | (staticCRC << 8); + staticCRC ^= ser_data; + staticCRC ^= (unsigned char)(staticCRC & 0xff) >> 4; + staticCRC ^= (staticCRC << 8) << 4; + staticCRC ^= ((staticCRC & 0xff) << 4) << 1; +} + + Index: webserver/example/EnergyMeters/Source/EnergyMeters/MetersIncludes.h =================================================================== --- webserver/example/EnergyMeters/Source/EnergyMeters/MetersIncludes.h (revision 61) +++ webserver/example/EnergyMeters/Source/EnergyMeters/MetersIncludes.h (revision 66) @@ -1,4 +1,8 @@ void initMeterItems(void); + +portCHAR checkRxOneByteCheckSum(void); +portCHAR checkRxTwoByteCheckSum(void); + unsigned long long getEpochTimeWithMs(void);