SHARE
TWEET

Untitled

a guest Jan 27th, 2017 7 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   //prog_char is depreciated,replace with 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. //typedef const char prog_char;
  25.  
  26. const byte crctable[256] PROGMEM = {
  27.     0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
  28.     0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
  29.     0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
  30.     0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
  31.     0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
  32.     0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
  33.     0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
  34.     0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
  35.     0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
  36.     0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
  37.     0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
  38.     0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
  39.     0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
  40.     0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
  41.     0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
  42.     0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
  43.     0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
  44.     0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
  45.     0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
  46.     0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
  47.     0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
  48.     0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
  49.     0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
  50.     0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
  51.     0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
  52.     0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
  53.     0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
  54.     0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
  55.     0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
  56.     0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
  57.     0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
  58.     0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
  59. };
  60.  
  61.  
  62. JETI_Box_class::JETI_Box_class() {
  63. // Class constructor
  64.     alarmEX=0;
  65.     nbValueEX=0;
  66.     frameSize=0;
  67.     valueEXToSend=0;
  68. }
  69.  
  70. void JETI_Box_class::Init(const __FlashStringHelper* sensorName) {
  71.     nameEX[0]=sensorName;
  72.     unitEX[0]=F(" ");
  73.     nbValueEX++;
  74. }
  75.  
  76. uint8_t JETI_Box_class::addData(const __FlashStringHelper* name, const __FlashStringHelper* unit) {
  77.    // Prepare EX data
  78.    nameEX[nbValueEX]=name;
  79.     unitEX[nbValueEX]=unit;
  80.     valueEX[nbValueEX]=0;
  81.     precisionEX[nbValueEX]=0;
  82.     nbValueEX++;
  83.     return(nbValueEX-1);
  84. }
  85.  
  86.  
  87. void JETI_Box_class::setValue(uint8_t ident, short* valuePtr) {
  88.     valueEX[ident]=(int*)valuePtr;
  89.     precisionEX[ident]=0;
  90. }
  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.  
  141. void JETI_Box_class::JetiBox(const __FlashStringHelper* line1, const __FlashStringHelper* line2)
  142. {
  143.   uint8_t i;
  144.   uint8_t length;
  145.   char ch;
  146.   bool empty;
  147.   prog_char *pline1 = ( prog_char * ) line1;
  148.   prog_char *pline2 = ( prog_char * ) line2;
  149.  
  150.   // 34 Byte Data Package
  151.   empty = false;
  152.   for (i=0; i<(LCDMaxPos/2);i++) {
  153.     if (!empty)
  154.     {
  155.         ch = pgm_read_byte_near(pline1 + i);
  156.         if (ch == 0)
  157.             empty = true;
  158.     }
  159.     if (!empty) {
  160.       jetiLcd[i] = ch;
  161.     } else {
  162.       jetiLcd[i] = ' ';
  163.     }
  164.   }
  165.  
  166.   empty = false;
  167.   for (i=0; i<(LCDMaxPos/2);i++) {
  168.     if (!empty)
  169.     {
  170.         ch = pgm_read_byte_near(pline2 + i);
  171.         if (ch == 0)
  172.             empty = true;
  173.     }
  174.     if (!empty) {
  175.       jetiLcd[i+(LCDMaxPos/2)] = ch;
  176.     } else {
  177.       jetiLcd[i+(LCDMaxPos/2)] = ' ';
  178.     }
  179.   }
  180. }
  181.  
  182.  
  183. void JETI_Box_class::JetiBox(const char* line)
  184. {
  185.   uint8_t i;
  186.   uint8_t length;
  187.  
  188.   // 34 Byte Data Package
  189.   length = strlen(line);
  190.   for (i=0; i<(LCDMaxPos);i++) {
  191.     if (i<length) {
  192.       jetiLcd[i] = line[i];
  193.     } else {
  194.       jetiLcd[i] = ' ';
  195.     }
  196.   }
  197. }
  198.  
  199.  
  200. /* 8-bit CRC polynomial X^8 + X^2 + X + 1 */
  201. #define POLY 0x07
  202. uint8_t update_crc (uint8_t crc, uint8_t crc_seed)
  203. {
  204. uint8_t crc_u;
  205. uint8_t i;
  206. crc_u = crc;
  207. crc_u ^= crc_seed;
  208. for (i=0; i<8; i++)
  209. {
  210. crc_u = ( crc_u & 0x80 ) ? POLY ^ ( crc_u << 1 ) : ( crc_u << 1 );
  211. }
  212. return crc_u;
  213. }
  214. uint8_t crc8fce (uint8_t *crc, uint8_t crc_lenght)
  215. {
  216. uint8_t crc_up = 0;
  217. uint8_t c;
  218. for(c=0;c < crc_lenght; c++) {
  219. crc_up = update_crc (crc[c], crc_up);
  220. }
  221. return crc_up;
  222. }
  223.  
  224. uint16_t uint14 (long value)                            
  225. {
  226.   if (value < 0)
  227.     return ((value >> 8) & 0x1F) | 0x80;        
  228.   else
  229.     return (value >> 8);                    
  230. }
  231.  
  232. uint8_t sensorFrameName = 0;
  233.  
  234. #define maxvals 6
  235.  
  236. #define JETI_REPEAT_ALARM 6
  237. uint8_t alarmCmpt = JETI_REPEAT_ALARM;
  238. const static uint8_t codage[4] = {0x52,0x1C,0x6C,0x23};
  239. bool JETI_Box_class::createFrame(uint8_t sendheader) {
  240.     //uint8_t key;
  241.     uint8_t crc8=0;
  242.     uint8_t i_Loop;
  243.     uint8_t identSend;
  244.     short value;
  245.     uint8_t *valeur;
  246.     int cmpt=0;
  247.     if (alarmEX) {
  248.        frame[cmpt]=0x7E;
  249.         ////bit9[cmpt]=false;
  250.         cmpt++;
  251.         frame[cmpt]=0x92;
  252.         //bit9[cmpt]=true;
  253.         cmpt++;
  254.         frame[cmpt]=0x23;
  255.         //bit9[cmpt]=true;
  256.         cmpt++;
  257.         frame[cmpt]=alarmEX;
  258.         //bit9[cmpt]=true;
  259.         cmpt++;
  260.         if (alarmCmpt) {
  261.             alarmCmpt--;
  262.         } else {
  263.             alarmEX=0;
  264.             alarmCmpt=JETI_REPEAT_ALARM;
  265.         }
  266.     }
  267.     if (!alarmEX ) {
  268.        frame[0]=0x7E;
  269.         //bit9[0]=false;
  270.        frame[1]=0x9F;
  271.         //bit9[1]=true;
  272.        frame[2]=0x00;
  273.         //bit9[2]=true;
  274.        frame[3]=JETI_SENSOR_ID1;
  275.         //bit9[3]=true;
  276.        frame[4]=JETI_SENSOR_ID2;
  277.         //bit9[4]=true;
  278.        frame[5]=JETI_SENSOR_ID3;
  279.         //bit9[5]=true;
  280.        frame[6]=JETI_SENSOR_ID4;
  281.         //bit9[6]=true;
  282.         //key=(uint8_t)random(0xFE)+1;
  283.         frame[7]=0;
  284.         //bit9[7]=true;
  285.         if (sendheader == 0) {
  286.             cmpt=8;
  287.             frame[2]=0x40;
  288.            
  289.             /*while (valueEX[valueEXToSend]==0) {
  290.                 valueEXToSend++;
  291.                 if (valueEXToSend>=nbValueEX) {
  292.                     valueEXToSend=0;
  293.                     break;
  294.                 }
  295.             }*/
  296.            
  297.             //valueEXToSend=1+((valueEXToSend-1)/3)*3;
  298.             for (i_Loop=0; i_Loop<maxvals; i_Loop++) { //two values only
  299.                 identSend=i_Loop+valueEXToSend;
  300.                 if (identSend>=nbValueEX) {
  301.                                 break;
  302.                 }
  303.                 if (valueEX[identSend]==0) {
  304.                     continue;
  305.                 }
  306.                 frame[cmpt]=0;
  307.                 // 5 for date/time 3 octets
  308.                 // 9 for GPS 4 octets
  309.                 frame[cmpt]=identSend<<4;
  310.                 //bit9[cmpt]=true;
  311.                 switch (precisionEX[identSend]) {
  312.                     case 0:
  313.                         value=*((short*)valueEX[identSend]);
  314.                         break;
  315.                     case 1:
  316.                     case 2:
  317.                     case 3:
  318.                         value=round(*((float*)valueEX[identSend])*pow(10,precisionEX[identSend]));
  319.                         break;
  320.                 }
  321.                 if (precisionEX[identSend]<4) {
  322.                         frame[cmpt]|=0x01;
  323.                         cmpt++;
  324.                         value=(value&0x9FFF)|(precisionEX[identSend]<<13);
  325.                         frame[cmpt]=(uint8_t)byte(value&0xFF);
  326.                         //bit9[cmpt]=true;
  327.                         cmpt++;
  328.                         frame[cmpt]=(uint8_t)byte((value>>8)&0xFF);
  329.                         //bit9[cmpt]=true;
  330.                         cmpt++;
  331.                 } else if (precisionEX[identSend]<6) {
  332.                     frame[cmpt]|=0x05;
  333.                     cmpt++;
  334.                     valeur=((uint8_t*)valueEX[identSend]);
  335.                     frame[cmpt]=valeur[2];
  336.                     //bit9[cmpt]=true;
  337.                     cmpt++;
  338.                     frame[cmpt]=valeur[1];
  339.                     //bit9[cmpt]=true;
  340.                     cmpt++;
  341.                     frame[cmpt]=valeur[0];
  342.                     frame[cmpt]&=0x1F;
  343.                     //bit9[cmpt]=true;
  344.                     if (precisionEX[identSend]==4) {
  345.                         frame[cmpt]|=0x20;
  346.                     }
  347.                     cmpt++;
  348.                 } else if (precisionEX[identSend]==9) {
  349.                     frame[cmpt]|=0x09;
  350.                     cmpt++;
  351.                     valeur=((uint8_t*)valueEX[identSend]);
  352.                     frame[cmpt]=valeur[3];
  353.                     //bit9[cmpt]=true;
  354.                     cmpt++;
  355.                     frame[cmpt]=valeur[2];
  356.                     //bit9[cmpt]=true;
  357.                     cmpt++;
  358.                     frame[cmpt]=valeur[1];
  359.                     //bit9[cmpt]=true;
  360.                     cmpt++;
  361.                     frame[cmpt]=valeur[0];
  362.                     //bit9[cmpt]=true;
  363.                     switch (valeur[0]) {
  364.                         case 'N':
  365.                             frame[cmpt]=0x00;
  366.                             break;
  367.                         case 'E':
  368.                             frame[cmpt]=0x20;
  369.                             break;
  370.                     }
  371.                     cmpt++;
  372.                 }
  373.             }
  374.             valueEXToSend=valueEXToSend+maxvals;
  375.             if (valueEXToSend>=nbValueEX) {
  376.                 valueEXToSend=0;
  377.             }
  378.  
  379.         } else {
  380.            
  381.             char name[16];
  382.             char unit[16];
  383.            
  384.             strcpy_P((char*)&name,( prog_char* )nameEX[sensorFrameName]);
  385.             strcpy_P((char*)&unit,( prog_char* )unitEX[sensorFrameName]);
  386.        
  387.             frame[8]=sensorFrameName;
  388.             //bit9[8]=true;
  389.             frame[9]=0;
  390.             frame[9]|=(strlen(name)<<3);
  391.             frame[9]|=(strlen(unit)&0x03);
  392.             //bit9[9]=true;
  393.             cmpt=10;
  394.             for (i_Loop=0;i_Loop<strlen(name);i_Loop++) {
  395.                 frame[cmpt]=name[i_Loop];
  396.                 //bit9[cmpt]=true;
  397.                 cmpt++;
  398.             }
  399.             for (i_Loop=0;i_Loop<strlen(unit);i_Loop++) {
  400.                 frame[cmpt]=unit[i_Loop];
  401.                 //bit9[cmpt]=true;
  402.                 cmpt++;
  403.             }
  404.             sensorFrameName++;
  405.             sensorFrameName%=nbValueEX;
  406.         }
  407.         // Finish the EX frame; //
  408.         frame[2]|=cmpt-2;
  409.         //if (!(frame[2] & 0x02)) {frame[8]^=0x3F;}
  410.         // Compute crc8 (last data);
  411.         crc8=0;
  412.             for (i_Loop=2; i_Loop<cmpt; i_Loop++) {
  413.             crc8=pgm_read_byte(&(crctable[(crc8 ^ frame[i_Loop])]));}
  414.         //crc8 = crc8fce(&frame[2],cmpt-2);
  415.         frame[cmpt]=crc8;
  416.         //bit9[cmpt]=true;
  417.         cmpt++;
  418.     }
  419.     // Send the value to print on jetiBox 2*16 characters
  420.     frame[cmpt]=0xFE;
  421.     //bit9[cmpt]=false;
  422.     middle_bit9 = cmpt;
  423.     cmpt++;
  424.     for (i_Loop=0;i_Loop<LCDMaxPos;i_Loop++) {
  425.        frame[cmpt]=jetiLcd[i_Loop];
  426.        //bit9[cmpt]=true;
  427.        cmpt++;
  428.     }
  429.     frame[cmpt]=0xFF;
  430.     //bit9[cmpt]=false;
  431.     cmpt++;
  432.     frameSize=cmpt;
  433.     return true;
  434. }
  435.  
  436. uint8_t JETI_Box_class::readbuttons() {
  437.     if (lastbuttons != buttons) {
  438.         return lastbuttons = buttons;
  439.     } else {
  440.         return JB_key_none;
  441.     }
  442. }
  443.  
  444. // Preinstantiate Objects //////////////////////////////////////////////////////
  445. //JETI_Box_class JB;
RAW Paste Data
Top