SHARE
TWEET

Untitled

a guest Jan 27th, 2017 6 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.   JETI_EX_SENSOR.cpp, Version 0.1
  3.   Mars 2012, by Denis Artru
  4.   alarm and jetibox display are based on work of Uwe Gartmann and Alexander Buschek
  5.   written for Arduino MEGA using rx2/tx2
  6.  
  7.      JETI_EX_SENSOR.h, Version 0.2
  8.      2014, by DevFor8.com, info@devfor8.com
  9.      modified for more items (15max)
  10.      modified for external sending (software serial can be used)
  11.      various fixes  
  12. */
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <avr/pgmspace.h>
  16. #include <JETI_EX_SENSOR.h>
  17. #define prog_char char PROGMEM
  18.  
  19. #define LCDBufferSize LCDMaxPos + 1
  20. #define JETI_WAIT 3
  21. uint8_t jetiLcd[LCDMaxPos];
  22. uint8_t buttons;
  23. uint8_t lastbuttons;
  24.  
  25. const byte crctable[256] PROGMEM = {
  26.     0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
  27.     0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
  28.     0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
  29.     0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
  30.     0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
  31.     0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
  32.     0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
  33.     0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
  34.     0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
  35.     0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
  36.     0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
  37.     0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
  38.     0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
  39.     0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
  40.     0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
  41.     0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
  42.     0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
  43.     0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
  44.     0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
  45.     0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
  46.     0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
  47.     0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
  48.     0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
  49.     0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
  50.     0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
  51.     0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
  52.     0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
  53.     0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
  54.     0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
  55.     0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
  56.     0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
  57.     0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
  58. };
  59.  
  60. JETI_Box_class::JETI_Box_class() {
  61. // Class constructor
  62.     alarmEX=0;
  63.     nbValueEX=0;
  64.     frameSize=0;
  65.     valueEXToSend=0;
  66. }
  67.  
  68. void JETI_Box_class::Init(const __FlashStringHelper* sensorName) {
  69.     nameEX[0]=sensorName;
  70.     unitEX[0]=F(" ");
  71.     nbValueEX++;
  72. }
  73.  
  74. uint8_t JETI_Box_class::addData(const __FlashStringHelper* name, const __FlashStringHelper* unit) {
  75.    // Prepare EX data
  76.     nameEX[nbValueEX]=name;
  77.     unitEX[nbValueEX]=unit;
  78.     valueEX[nbValueEX]=0;
  79.     precisionEX[nbValueEX]=0;
  80.     nbValueEX++;
  81.     return(nbValueEX-1);
  82. }
  83.  
  84. void JETI_Box_class::setValue(uint8_t ident, short* valuePtr) {
  85.     valueEX[ident]=(int*)valuePtr;
  86.     precisionEX[ident]=0;
  87. }
  88. void JETI_Box_class::setValueBig(uint8_t ident, int* valuebig) {
  89.     valueEX[ident]=(int*)valuebig;
  90.     precisionEX[ident]=4;
  91. }
  92. void JETI_Box_class::setValue(uint8_t ident, volatile float* valuePtr, uint8_t precision) {
  93.     valueEX[ident]=(int*)valuePtr;
  94.     precisionEX[ident]=precision;
  95. }
  96. void JETI_Box_class::setValueDate(uint8_t ident, uint8_t date[3]) {
  97.     valueEX[ident]=(int*)date;
  98.     precisionEX[ident]=4;
  99. }
  100. void JETI_Box_class::setValueTime(uint8_t ident, uint8_t time[3]) {
  101.     valueEX[ident]=(int*)time;
  102.     precisionEX[ident]=5;
  103. }
  104. void JETI_Box_class::setValueGPS(uint8_t ident, uint8_t coordinate[4]) {
  105.     valueEX[ident]=(int*)coordinate;
  106.     precisionEX[ident]=9;
  107. }
  108. void JETI_Box_class::unsetValue(uint8_t ident) {
  109.     valueEX[ident]=0;
  110.     precisionEX[ident]=0;
  111. }
  112.  
  113. void JETI_Box_class::alarm(char alarmLetter) {
  114.     alarmEX=alarmLetter;
  115. }
  116.  
  117. void JETI_Box_class::JetiBox(const char* line1, const char* line2) {
  118.   uint8_t i;
  119.   uint8_t length;
  120.  
  121.   // 34 Byte Data Package
  122.   length = strlen(line1);
  123.   for (i=0; i<(LCDMaxPos/2);i++) {
  124.     if (i<length) {
  125.       jetiLcd[i] = line1[i];
  126.     } else {
  127.       jetiLcd[i] = ' ';
  128.     }
  129.   }
  130.   length = strlen(line2);
  131.   for (i=0; i<(LCDMaxPos/2);i++) {
  132.     if (i<length) {
  133.       jetiLcd[i+(LCDMaxPos/2)] = line2[i];
  134.     } else {
  135.       jetiLcd[i+(LCDMaxPos/2)] = ' ';
  136.     }
  137.   }
  138. }
  139.  
  140. void JETI_Box_class::JetiBox(const __FlashStringHelper* line1, const __FlashStringHelper* line2)
  141. {
  142.   uint8_t i;
  143.   uint8_t length;
  144.   char ch;
  145.   bool empty;
  146.   prog_char *pline1 = ( prog_char * ) line1;
  147.   prog_char *pline2 = ( prog_char * ) line2;
  148.  
  149.   // 34 Byte Data Package
  150.   empty = false;
  151.   for (i=0; i<(LCDMaxPos/2);i++) {
  152.     if (!empty)
  153.     {
  154.         ch = pgm_read_byte_near(pline1 + i);
  155.         if (ch == 0)
  156.             empty = true;
  157.     }
  158.     if (!empty) {
  159.       jetiLcd[i] = ch;
  160.     } else {
  161.       jetiLcd[i] = ' ';
  162.     }
  163.   }
  164.  
  165.   empty = false;
  166.   for (i=0; i<(LCDMaxPos/2);i++) {
  167.     if (!empty)
  168.     {
  169.         ch = pgm_read_byte_near(pline2 + i);
  170.         if (ch == 0)
  171.             empty = true;
  172.     }
  173.     if (!empty) {
  174.       jetiLcd[i+(LCDMaxPos/2)] = ch;
  175.     } else {
  176.       jetiLcd[i+(LCDMaxPos/2)] = ' ';
  177.     }
  178.   }
  179. }
  180.  
  181. void JETI_Box_class::JetiBox(const char* line)
  182. {
  183.   uint8_t i;
  184.   uint8_t length;
  185.  
  186.   // 34 Byte Data Package
  187.   length = strlen(line);
  188.   for (i=0; i<(LCDMaxPos);i++) {
  189.     if (i<length) {
  190.       jetiLcd[i] = line[i];
  191.     } else {
  192.       jetiLcd[i] = ' ';
  193.     }
  194.   }
  195. }
  196.  
  197. /* 8-bit CRC polynomial X^8 + X^2 + X + 1 */
  198. #define POLY 0x07
  199. uint8_t update_crc (uint8_t crc, uint8_t crc_seed)
  200. {
  201. uint8_t crc_u;
  202. uint8_t i;
  203. crc_u = crc;
  204. crc_u ^= crc_seed;
  205. for (i=0; i<8; i++)
  206. {
  207. crc_u = ( crc_u & 0x80 ) ? POLY ^ ( crc_u << 1 ) : ( crc_u << 1 );
  208. }
  209. return crc_u;
  210. }
  211. uint8_t crc8fce (uint8_t *crc, uint8_t crc_lenght)
  212. {
  213. uint8_t crc_up = 0;
  214. uint8_t c;
  215. for(c=0;c < crc_lenght; c++) {
  216. crc_up = update_crc (crc[c], crc_up);
  217. }
  218. return crc_up;
  219. }
  220.  
  221. uint16_t uint14 (long value)                            
  222. {
  223.   if (value < 0)
  224.     return ((value >> 8) & 0x1F) | 0x80;        
  225.   else
  226.     return (value >> 8);                   
  227. }
  228.  
  229. uint8_t sensorFrameName = 0;
  230.  
  231. #define maxvals 6
  232.  
  233. #define JETI_REPEAT_ALARM 6
  234. uint8_t alarmCmpt = JETI_REPEAT_ALARM;
  235. const static uint8_t codage[4] = {0x52,0x1C,0x6C,0x23};
  236. bool JETI_Box_class::createFrame(uint8_t sendheader) {
  237.     uint8_t crc8=0;
  238.     uint8_t i_Loop;
  239.     uint8_t identSend;
  240.     int value; //was short
  241.     uint8_t *valeur;
  242.     uint8_t *valeur2;
  243.     int cmpt=0;
  244.     if (alarmEX) {
  245.        frame[cmpt]=0x7E;
  246.         cmpt++;
  247.         frame[cmpt]=0x92;
  248.         cmpt++;
  249.         frame[cmpt]=0x23;
  250.         cmpt++;
  251.         frame[cmpt]=alarmEX;
  252.         cmpt++;
  253.         if (alarmCmpt) {
  254.             alarmCmpt--;
  255.         } else {
  256.             alarmEX=0;
  257.             alarmCmpt=JETI_REPEAT_ALARM;
  258.         }
  259.     }
  260.     if (!alarmEX ) {
  261.        frame[0]=0x7E;
  262.        frame[1]=0x9F;
  263.        frame[2]=0x00;
  264.        frame[3]=JETI_SENSOR_ID1;
  265.        frame[4]=JETI_SENSOR_ID2;
  266.        frame[5]=JETI_SENSOR_ID3;
  267.        frame[6]=JETI_SENSOR_ID4;
  268.         frame[7]=0;
  269.         if (sendheader == 0) {
  270.             cmpt=8;
  271.             frame[2]=0x40;
  272.            
  273.             for (i_Loop=0; i_Loop<maxvals; i_Loop++) {
  274.                 identSend=i_Loop+valueEXToSend;
  275.                 if (identSend>=nbValueEX) {
  276.                                 break;
  277.                 }
  278.                 if (valueEX[identSend]==0) {
  279.                     continue;
  280.                 }
  281.                 frame[cmpt]=0;
  282.                 // 5 for date/time 3 octets
  283.                 // 9 for GPS 4 octets
  284.                 frame[cmpt]=identSend<<4;
  285.                 switch (precisionEX[identSend]) {
  286.                     case 0:
  287.                         value=*((int*)valueEX[identSend]);
  288.                         break;
  289.                     case 1:
  290.                     case 2:
  291.                     case 3:
  292.                         value=round(*((float*)valueEX[identSend])*pow(10,precisionEX[identSend]));
  293.                     break;
  294.                 }
  295.                 if (precisionEX[identSend]<4) {
  296.                     frame[cmpt]|=0x01;
  297.                     cmpt++;
  298.                     value=(value&0x9FFF)|(precisionEX[identSend]<<13);
  299.                     frame[cmpt]=(uint8_t)byte(value&0xFF);
  300.                     cmpt++;
  301.                     frame[cmpt]=(uint8_t)byte((value>>8)&0xFF);
  302.                     cmpt++;
  303.                 } else if (precisionEX[identSend]==4) {
  304.                     frame[cmpt]|=0x04;
  305.                     cmpt++;
  306.                     valeur2=((uint8_t*)valueEX[identSend]);
  307.                     frame[cmpt]=valeur2[2]>>8;
  308.                     cmpt++;
  309.                     frame[cmpt]=valeur2[1];
  310.                     cmpt++;
  311.                     frame[cmpt]=valeur2[0];
  312.                     cmpt++;
  313.                     frame[cmpt]&=0x00;
  314.                     cmpt++;
  315.                 } else if (precisionEX[identSend]<6) {
  316.                     frame[cmpt]|=0x05;
  317.                     cmpt++;
  318.                     valeur=((uint8_t*)valueEX[identSend]);
  319.                     frame[cmpt]=valeur[2]>>8;
  320.                     cmpt++;
  321.                     frame[cmpt]=valeur[1];
  322.                     cmpt++;
  323.                     frame[cmpt]=valeur[0];
  324.                     frame[cmpt]&=0x1F;
  325.                     if (precisionEX[identSend]==4) {
  326.                         frame[cmpt]|=0x20;
  327.                     }
  328.                     cmpt++;
  329.                 } else if (precisionEX[identSend]==9) {
  330.                     frame[cmpt]|=0x09;
  331.                     cmpt++;
  332.                     valeur=((uint8_t*)valueEX[identSend]);
  333.                     frame[cmpt]=valeur[3];
  334.                     cmpt++;
  335.                     frame[cmpt]=valeur[2];
  336.                     cmpt++;
  337.                     frame[cmpt]=valeur[1];
  338.                     cmpt++;
  339.                     frame[cmpt]=valeur[0];
  340.                     switch (valeur[0]) {
  341.                         case 'N':
  342.                             frame[cmpt]=0x00;
  343.                             break;
  344.                         case 'E':
  345.                             frame[cmpt]=0x20;
  346.                             break;
  347.                 }
  348.                     cmpt++;
  349.                 }
  350.             }
  351.             valueEXToSend=valueEXToSend+maxvals;
  352.             if (valueEXToSend>=nbValueEX) {
  353.                 valueEXToSend=0;
  354.             }
  355.         } else {
  356.             char name[16];
  357.             char unit[16];
  358.            
  359.             strcpy_P((char*)&name,( prog_char* )nameEX[sensorFrameName]);
  360.             strcpy_P((char*)&unit,( prog_char* )unitEX[sensorFrameName]);
  361.        
  362.             frame[8]=sensorFrameName;
  363.             frame[9]=0;
  364.             frame[9]|=(strlen(name)<<3);
  365.             frame[9]|=(strlen(unit)&0x03);
  366.             cmpt=10;
  367.             for (i_Loop=0;i_Loop<strlen(name);i_Loop++) {
  368.                 frame[cmpt]=name[i_Loop];
  369.                 cmpt++;
  370.             }
  371.             for (i_Loop=0;i_Loop<strlen(unit);i_Loop++) {
  372.                 frame[cmpt]=unit[i_Loop];
  373.                 cmpt++;
  374.             }
  375.             sensorFrameName++;
  376.             sensorFrameName%=nbValueEX;
  377.         }
  378.         // Finish the EX frame; //
  379.         frame[2]|=cmpt-2;
  380.         // Compute crc8 (last data);
  381.         crc8=0;
  382.             for (i_Loop=2; i_Loop<cmpt; i_Loop++) {
  383.             crc8=pgm_read_byte(&(crctable[(crc8 ^ frame[i_Loop])]));}
  384.         frame[cmpt]=crc8;
  385.         cmpt++;
  386.     }
  387.     // Send the value to print on jetiBox 2*16 characters
  388.     frame[cmpt]=0xFE;
  389.     middle_bit9 = cmpt;
  390.     cmpt++;
  391.     for (i_Loop=0;i_Loop<LCDMaxPos;i_Loop++) {
  392.        frame[cmpt]=jetiLcd[i_Loop];
  393.        cmpt++;
  394.     }
  395.     frame[cmpt]=0xFF;
  396.     cmpt++;
  397.     frameSize=cmpt;
  398.     return true;
  399. }
  400.  
  401. uint8_t JETI_Box_class::readbuttons() {
  402.     if (lastbuttons != buttons) {
  403.         return lastbuttons = buttons;
  404.     } else {
  405.         return JB_key_none;
  406.     }
  407. }
RAW Paste Data
Top