Logger Shield and Negative Numbers

Well, the logger project has been going well, with all the holdups one would expect, and a few that were unexpected!

This falls under the latter. I have been sucessfully logging the data from a remote XBee with 4 TMP36 sensors. Goes on the card, and is in a format that is easy to export to Excel.

I added another XBee remote, and only had 1 TMP36 to attach to it. (Gotta order more!) So I grounded the other 3 inputs, and the serial monitor displayed -57* for these inputs. As expected. However, on reviewing the data on the SD card, I was surprised to find the number 4,294,967,239 instead of -57! This is a snippet of code that produces the numbers:

Code: Select all | TOGGLE FULL SIZE
`        int analogChannelData2 = (packet <<8) | packet;  // reads byte 14, shifts it over 8 bits, and appends byte 15 to it to form the raw data variable from the A/D converter reading        Serial.print(analogChannelData2);Serial.println(" TMP36 2 reading ");Serial.println("");  // prints raw A/D readingfor debugging        Serial.print(packet, HEX);Serial.print(" byte 14  ");Serial.print(packet, HEX); Serial.print(" byte 15  "); // prints byte 14 and byte 15 for debugging        float v2 = (analogChannelData2 * 3.25) / 10.24; float tempC2 = (v2 - 50); // converts raw A/D signal to deg C        float tempF2 = (tempC2 * 9 / 5) + 32; Serial.print(tempF2);Serial.println("  Temp F 2 ");Serial.println("");  // converts C to F and prints it.        writeNumber(file, tempF2);                  // add value for tempF2  to line of data         writeString(file, " , ");      // comma to separate readings for export to excel`

Second line up from the bottom, is 'writeNumber(file, tempF2);' , This is the temperature that was derived from the raw TMP36 reading. It can go negative.

Changing that code to:

Code: Select all | TOGGLE FULL SIZE
`        writeNumber(file, analogChannelData2);                  // add value for TMP36 2 to line of data         writeString(file, " , ");      // comma to separate readings for export to excel`

Produced this: Which I can work with, I will just do the math in Excel.

What, if anything, can I do to properly store the negative values on the SD card?

EDIT- Right after posting, I had an idea...maybe convert tempFx to an integer? (int)
Code: Select all | TOGGLE FULL SIZE
`        writeNumber(file, int(tempF3));                  // add value for tempF3 to line of data         writeString(file, " , ");      // comma to separate readings for export to excel`

but still got the 4.2 billion reading. Rats.
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

WriteNumber's second argument is uint32_t so it does not handle negative numbers.

SdFile has Print as a parent class so you can print to a file like this:

Code: Select all | TOGGLE FULL SIZE
`  file.print(tempF2);  file.print(',');`
fat16lib

Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: Logger Shield and Negative Numbers

Thanks once again, fat16lib.

I am suffering somewhat from my 'cut and paste' education.

"uint32_t" means nothing to me yet, and was in the 'unknown' category. I am learning more and more however.

I started from the SDFatWrite example, and have to learn how to use the SD library more completely. Your code sure looks a heck of a lot simpler!!!!

Even moreThanks, and on I go to learn about 'uint32_t'. Thank goodness for one more day off...
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

The uint32 should be easy to work around in your favorite spreadsheet--just subtract 2^32 (4294967296) from any value greater than 2^31-1 (2147483647).
--Paul

A wholly owned subsidiary of:
Persephone: DL R+W+B C 7 X L W C++ I++ T+ A E H++ S+ V-- F+ Q P B PA+ PL
Aldebaran: DM Rt H 5 Y L- W+ C+ I++ T++ A+++ E H++ S+ V+ F++ Q+ P B++ PA- PL-- pstemari

Posts: 310
Joined: Sun Mar 21, 2010 6:10 pm
Location: Seattle, WA

Re: Logger Shield and Negative Numbers

LOL! Thanks for the overestimation of my current abilities. :) I am still looking to find out what a 'uint32' is... Unsigned INTeger ...32 somethings..

It might be easier just to import the readings from the TMP36, and do the temperature conversions there. Might do that.

Thank you for another bit of wisdom.
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

Just use file.print() - it will handle negative values.
fat16lib

Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: Logger Shield and Negative Numbers

I did try that, but it would not seem to convert to an integer. Returned what appeared to be the integer and decimal value all together as an integer. IE: 78.181579 degrees was sent as 78181579.

Even taking the tempF[x] value and converting it to an integer named q - int q = int(tempF[x]); and then print.file(q); printed the larger number.

I realize that this is the period before another 'breakthrough in knowledge', and I am getting closer. Just a wee bit tired, as I have been at this for 15 hours today. So... please be patient with me. ( Like you have not been already! You and ChuckM have the patience of saints.)

Did just find this, somewhat (!) enlightening..http://www.arduino.cc/cgi-bin/yabb2/YaB ... 59022445/6

Indeed it seems to be common practice (even by the arduino core team) to use the uint8_t as defined by the AVR GCC compiler for unsigned 8 bit values in core and library code.

AhHA!! Soo... uint8_t buf; is an array of 10 Unsigned INTegers 8 bits in length named 'buf'. No wonder it wouldn't do a negative!
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

If you can get the correct value with
Code: Select all | TOGGLE FULL SIZE
`  Serial.print(x);`

for a signed variable x then
Code: Select all | TOGGLE FULL SIZE
`  file.print(x);`

will put the same value on the SD. The same code is used for 'print' in both cases.
fat16lib

Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: Logger Shield and Negative Numbers

Well, this code:
Code: Select all | TOGGLE FULL SIZE
`        tempF[a] = (tempC * 9 / 5) + 32; Serial.println(tempF[a]);//Serial.println("  Temp F");Serial.println(a);  // converts C to F and prints it.        //writeNumber(file, tempF[a]);                  // add value for tempF of pin(pinNum) to line of data         //writeString(file, " , ");      // comma to separate readings for export to excel        file.print(tempF[a]);        file.print(' , ');`

Produced this on the serial monitor: and this on the SD card: I think it may just be running into the way that the different libraries deal with float numbers?
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

Just making sure that I did it right last time...

This code:

Code: Select all | TOGGLE FULL SIZE
`        tempF[a] = (tempC * 9 / 5) + 32; Serial.println(int(tempF[a]));//Serial.println("  Temp F");Serial.println(a);  // converts C to F and prints it.        //writeNumber(file, tempF[a]);                  // add value for tempF of pin(pinNum) to line of data         //writeString(file, " , ");      // comma to separate readings for export to excel        file.print(int(tempF[a]));        file.print(' , ');`

Produced nice integers on the serial monitor.(80/81/89/81) But still the long numbers on the SD card. and didn't print the " , " between numbers...

Just making sure I didn't muck it up last time. I am pretty tired.

May call it a night and hit it early. Got one more day off.

THANK YOU for the help. I hope that my bumbling around has been entertaining :wink: I sure have been having fun learning.
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

You are close! The problem now is:

Code: Select all | TOGGLE FULL SIZE
`  file.print(' , ');`

This will print as 11296. If you want a single character ',' remove the spaces and print
Code: Select all | TOGGLE FULL SIZE
`  file.print(',');`

if you want a space on each side of the comma print
Code: Select all | TOGGLE FULL SIZE
`  file.print(" , ");`

try the following:
Code: Select all | TOGGLE FULL SIZE
`  Serial.print(' , ');  Serial.print(',');  Serial.println(" , ");`

The result is:
11296, ,

In C++, the base for Arduino, 'a' with a single character is type char and print() treats it as ASCII. 'aa' with two or more characters is type int and print() treats it as a number.
fat16lib

Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: Logger Shield and Negative Numbers

Yippee!! I was hoping a nights sleep would reveal my errors. I was getting pretty sloppy typing at that point.

THAT is one complete explanation. I was thinking the .5*C resolution of the sensors was giving the same decimal result.

Well, ran it again.

Code:

Code: Select all | TOGGLE FULL SIZE
`/* * This sketch was started using the SdFatWrite Example and grew from there. *  * * V5 changes the LCD to a 20x4 *  */#include <SdFat.h>            // library for SD card#include <SdFatUtil.h>        // library for SD card#include <Wire.h>             // i2c  ' one wire ' library#include <RTClib.h>           // real time clock library#include <LiquidCrystal.h>    // liquid crystal libraryLiquidCrystal lcd(4, 5, 6, 7, 8, 9);  // LCD/Arduino pin order: RS pin / D4, EN pin / D5, DB4 pin / D6, DB5 pin / D7, DB6 pin / D8, DB8 pin / D9  - because Data Logger Shield uses D10 - D13RTC_DS1307 RTC;                     // start Real Time ClockSd2Card card;                      // start SD card functionsSdVolume volume;                  //SdFile root;                     //SdFile file;                    //unsigned int linecount = 0;         // for debugging in serial monitor, and a 'heartbeat' on the LCD. unsigned to allow greater sample count.int dataLine = 0;         // variable to control number of lines of data in each WRITExx.txt file on SD cardint packet;   // variable for packet size, in this case 18 bytes. (0 - 17) (1 sensor=14, 2=16,3=18 4=20,etc)// store error strings in flash to save RAM#define error(s) error_P(PSTR(s))               // 5/17/10 from here to "*END*" was cut and paste, and I am working on translating it :) void error_P(const char *str){  PgmPrint("error: ");  SerialPrintln_P(str);  if (card.errorCode()) {    PgmPrint("SD error: ");    Serial.print(card.errorCode(), HEX);    Serial.print(',');    Serial.println(card.errorData(), HEX);  }  while(1);}/* * Write CR LF to a file */void writeCRLF(SdFile &f)            // does a carriage return in .txt file?{  f.write((uint8_t *)"\r\n", 2);}void writeNumber(SdFile &f, uint32_t n){  uint8_t buf;      uint8_t i = 0;  do {    i++;    buf[sizeof(buf) - i] = n%10 + '0';    n /= 10;  } while (n);  f.write(&buf[sizeof(buf) - i], i);}/* * Write a string to a file */void writeString(SdFile &f, char *str){  uint8_t n;  for (n = 0; str[n]; n++);  f.write((uint8_t *)str, n);                      //     *  END  *}void setup(void){  Wire.begin();           //enable i2c   lcd.begin(20, 4);      // set up the LCD's number of rows and columns  Serial.begin(9600);     //start serial port  RTC.begin();           //Start Real Time Clock    if (!card.init()) error("card.init");    // initialize the SD card    if (!volume.init(card)) error("volume.init");  // initialize a FAT volume    if (!root.openRoot(volume)) error("openRoot");   // open the root directory    char name[] = "WRITE00.TXT";     // create a new file  for (uint8_t i = 0; i < 100; i++) {    name = i/10 + '0';    name = i%10 + '0';    if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;  }  if (!file.isOpen()) error ("file.create");  Serial.print("Writing to: ");  Serial.println(name);  lcd.setCursor(0,3);  lcd.print(name);  }void readPacket() {  if (Serial.available() > 0) {    int b = Serial.read();    if (b == 0x7E) {      packet = b;      packet = readByte();      packet = readByte();      int dataLength = (packet << 8) | packet;      for(int i=1;i<=dataLength;i++) {        packet[2+i] = readByte();      }      int apiID = packet;      int SenID = (packet << 8) | packet;      packet[3+dataLength] = readByte(); // checksum      printPacket(dataLength+4);      if (apiID == 0x83) {           // if string sent has the fourth byte (= API ID) 0x83        int s = 1;   // variable to print the readings from the XBee on the proper line of the LCD for that sensor group        if (SenID == 0x5678){ s = 1;}   // sensor group 1        if (SenID == 0x5679){ s = 2;}   //sensor group 2        int analogSampleIndex = 13; // byte-1 for where analog data starts in the string        int sigStrg = packet ;   // read the seventh byte in the string = signal strength        lcd.setCursor(0, 0);    // put the LCD cursor to row , column0  to start signal strength display line on LCD        //char signal[] = "Sig-";       // added to try to disply Sig-  before signal strength on LCD        //lcd.print(signal);            //                      ""        lcd.print("Sig-");              // Used to work, now doesnt. Un-commented it again to see if it worked, commented out patch above. Still didnt LCD print.        Serial.print(sigStrg);        delay (50);  // added to see if it helped serial.print problem        char dBm[]= "dBm";         Serial.println(dBm); Serial.println("");   // displays signal strength on serial monitor, also adds a line return to format         // Serial.println("  dBm  "); Serial.println("");   STOPPED WORKING        lcd.setCursor(4, 0);    // put the LCD cursor to row3 , column0  to start signal strength display line on LCD        lcd.print(sigStrg);         // print signal strength        lcd.print(dBm);        int pac = 11;        int h = 0;  // for positioning the temp on LCD display        int ADdata;        float tempF;       for (int a=1;a<5;a++) {        ADdata[a] = (packet[pac] <<8) | packet[(pac + 1)];  // reads byte 12, shifts it over 8 bits, and appends byte 13 to it to form the raw data variable from the A/D converter reading        Serial.println(ADdata[a]);Serial.print(" TMP36");Serial.println(a);  // prints raw A/D readingfor debugging        int r = FreeRam();        Serial.println(r);        //Serial.print(packet[pac], HEX);Serial.print(" byte 12  ");Serial.print(packet[(pac + 1)], HEX); Serial.print(" byte 13  "); // prints byte 12 and byte 13 for debugging        float v = (ADdata[a] * 3.25) / 10.24; float tempC = (v - 50); // converts raw A/D signal to deg C        tempF[a] = (tempC * 9 / 5) + 32; Serial.println(int(tempF[a]));//Serial.println("  Temp F");Serial.println(a);  // converts C to F and prints it.        //writeNumber(file, tempF[a]);                  // add value for tempF of pin(pinNum) to line of data         //writeString(file, " , ");      // comma to separate readings for export to excel        file.print(int(tempF[a]));        file.print(" , ");        lcd.setCursor(h, s);    // put the LCD cursor to row2 , column0  to start temp display line on LCD         if (tempF[a] < 100 && tempF[a] > 0)        // puts a '0' before 10-99 to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        if (tempF[a] < 10 && tempF[a] >= 0)        // puts a '0' before single digits to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        lcd.print(int (tempF[a]) );         // print tempF1        pac += 2;        h += 5;               }                   }    }      }} void loop(void) {    Serial.print(linecount); Serial.print(" start ");    // serial output for debugging      for ( dataLine = 0; dataLine < 30; dataLine ++) {         // larger number (divided by PinNumMAX) determines how many lines of data per WRITExx.txt file.        readPacket();    lcd.setCursor(14, 3);           //Position cursor for linecount     lcd.print(linecount);          // put linecount on LCD          Serial.println(" ");                    // puts space in when debugging                                          Serial.print(linecount); Serial.print("= linecount  ");  // serial print for debugging      DateTime now = RTC.now();               // Read RTC      Serial.print("TEST RTC ");      Serial.print(now.hour(), DEC);      Serial.print(":");      Serial.print(now.minute(), DEC);        // Gets minute from RTC       Serial.print(":");                      // puts the ":" between the minute and second      Serial.print(now.second(), DEC);      //Gets second from RTC - for debugging      Serial.println("   ");                  // space to format serial table better      lcd.setCursor(12, 0);                  // shows time on top right of LCD      lcd.print(now.hour(), DEC); lcd.print(":");    // displays current hour on LCD      if ((now.minute()) < 10)        // puts a '0' before single digits to preserve format on LCD      {                              //        lcd.print("0");             //       }                            //      lcd.print(now.minute(), DEC); lcd.print(":");    // displays current minute on LCD      if ((now.second()) < 10)        // puts a '0' before single digits to preserve format on LCD      {                              //        lcd.print("0");             //      }                            //      lcd.print(now.second(), DEC);     // display seconds on LCD          writeNumber(file, now.hour());     // timestamp hour      writeString(file, ":");            // format time with "  :  "      writeNumber(file, now.minute());   // timestamp minute      writeString(file, ":");            // format time with "  :  "      writeNumber(file, now.second());   // timestamp second      lcd.setCursor(12, 3);    // put the LCD cursor to row4 , column12        lcd.print("L=");         // print L for linecount.      writeCRLF(file);                        // goes to new line in text data file      linecount++;                            // adavances linecount for serial debugging and LCD                      delay (2000);                         // delay to adjust overall sample rate  }    file.close();                           // close file and force write of all data to the SD card  Serial.println("Done");                 // for debugging  char name[] = "WRITE00.TXT";           // create a new file for next batch of data  for (uint8_t i = 0; i < 100; i++) {    // will only do 100 SD file writes 5/17/10    name = i/10 + '0';                // the "char name" [fifth digit] = i/10 followed by a printed " 0 "    name = i%10 + '0';                // the "char name" [sixth digit] = i % (what?) followed by a " 0 "    if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;  }  if (!file.isOpen()) error ("file.create");  Serial.print("Writing to: ");  Serial.println(name);  lcd.setCursor(0,3);  lcd.print(name); }void printPacket(int l) {  for(int i=0;i < l;i++) {    if (packet[i] < 0xF) {      // if the packet value is HEX F or lower      Serial.print(0);         //print leading zero for single digit values    }    Serial.print(packet[i], HEX);    Serial.print(" ");  }  Serial.println(" new string ");Serial.println("");}int readByte() {    while (true) {      if (Serial.available() > 0) {      return Serial.read();    }  }} `

Results on Serial monitor: Results on SD card: Oh well, still wont print commas. Seems to have extra and missing data also.

I am going to try some earlier versions and see how they run, and what I added that messed things up. I tried to go 'step by step', and having a known state to revert to.
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

Thinking with a clear mind, I ponder... What has been the biggest PITA in this project?

The RTC, or Real Time Clock on the Data Logger Shield. I commented it and the 1-wire library out... and Voila!!

Code: Select all | TOGGLE FULL SIZE
`/* * This sketch was started using the SdFatWrite Example and grew from there. *  * * V5 changes the LCD to a 20x4 *  */#include <SdFat.h>            // library for SD card#include <SdFatUtil.h>        // library for SD card//#include <Wire.h>             // i2c  ' one wire ' library//#include <RTClib.h>           // real time clock library#include <LiquidCrystal.h>    // liquid crystal library// initialize the library with the numbers of the interface pinsLiquidCrystal lcd(4, 5, 6, 7, 8, 9);  // LCD/Arduino pin order: RS pin / D4, EN pin / D5, DB4 pin / D6, DB5 pin / D7, DB6 pin / D8, DB8 pin / D9  - because Data Logger Shield uses D10 - D13//RTC_DS1307 RTC;                     // start Real Time ClockSd2Card card;                      // start SD card functionsSdVolume volume;                  //SdFile root;                     //SdFile file;                    //unsigned int linecount = 0;         // for debugging in serial monitor, and a 'heartbeat' on the LCD. unsigned to allow greater sample count.int dataLine = 0;         // variable to control number of lines of data in each WRITExx.txt file on SD cardint packet;   // variable for packet size, in this case 18 bytes. (0 - 17) (1 sensor=14, 2=16,3=18 4=20,etc)int analogSamples;// store error strings in flash to save RAM#define error(s) error_P(PSTR(s))               // 5/17/10 from here to "*END*" was cut and paste, and I am working on translating it :) void error_P(const char *str){  PgmPrint("error: ");  SerialPrintln_P(str);  if (card.errorCode()) {    PgmPrint("SD error: ");    Serial.print(card.errorCode(), HEX);    Serial.print(',');    Serial.println(card.errorData(), HEX);  }  while(1);}/* * Write CR LF to a file */void writeCRLF(SdFile &f)            // does a carriage return in .txt file?{  f.write((uint8_t *)"\r\n", 2);}/* * Write an unsigned number to a file */void writeNumber(SdFile &f, uint32_t n){  uint8_t buf;  uint8_t i = 0;  do {    i++;    buf[sizeof(buf) - i] = n%10 + '0';    n /= 10;  } while (n);  f.write(&buf[sizeof(buf) - i], i);}/* * Write a string to a file */void writeString(SdFile &f, char *str){  uint8_t n;  for (n = 0; str[n]; n++);  f.write((uint8_t *)str, n);                      //     *  END  *}void setup(void){  //Wire.begin();           //enable i2c   lcd.begin(20, 4);      // set up the LCD's number of rows and columns  Serial.begin(9600);     //start serial port  //RTC.begin();           //Start Real Time Clock  //Serial.println();                                 //  //Serial.println("Type any character to start");   //  //while (!Serial.available());                    // comment out these 3 lines to 'autostart'    if (!card.init()) error("card.init");    // initialize the SD card    if (!volume.init(card)) error("volume.init");  // initialize a FAT volume    if (!root.openRoot(volume)) error("openRoot");   // open the root directory    char name[] = "WRITE00.TXT";     // create a new file  for (uint8_t i = 0; i < 100; i++) {    name = i/10 + '0';    name = i%10 + '0';    if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;  }  if (!file.isOpen()) error ("file.create");  Serial.print("Writing to: ");  Serial.println(name);  lcd.setCursor(0,3);  lcd.print(name);  }void readPacket() {  if (Serial.available() > 0) {    int b = Serial.read();    if (b == 0x7E) {      packet = b;      packet = readByte();      packet = readByte();      int dataLength = (packet << 8) | packet;      for(int i=1;i<=dataLength;i++) {        packet[2+i] = readByte();      }      int apiID = packet;      int SenID = (packet << 8) | packet;      packet[3+dataLength] = readByte(); // checksum      printPacket(dataLength+4);      if (apiID == 0x83) {           // if string sent has the fourth byte (= API ID) 0x83        int s = 1;        if (SenID == 0x5678){ s = 1;   }        if (SenID == 0x5679){ s = 2;}        int analogSampleIndex = 13; // byte-1 for where analog data starts in the string        int sigStrg = packet ;   // read the seventh byte in the string = signal strength        lcd.setCursor(0, 0);    // put the LCD cursor to row , column0  to start signal strength display line on LCD        char signal[] = "Sig-"; lcd.print(signal);        Serial.print(sigStrg);        delay (50);  // added to see if it helped serial.print problem        char dBm[]= "dBm";         Serial.println(dBm); Serial.println("");   // displays signal strength on serial monitor, also adds a line return to format         // Serial.println("  dBm  "); Serial.println("");   STOPPED WORKING        lcd.setCursor(4, 0);    // put the LCD cursor to row3 , column0  to start signal strength display line on LCD        lcd.print(sigStrg);         // print signal strength        lcd.print(dBm);                        int analogChannelData = (packet <<8) | packet;  // reads byte 12, shifts it over 8 bits, and appends byte 13 to it to form the raw data variable from the A/D converter reading        Serial.print(analogChannelData);Serial.println(" TMP36 1  ");Serial.println("");  // prints raw A/D readingfor debugging        Serial.print(packet, HEX);Serial.print(" byte 12  ");Serial.print(packet, HEX); Serial.print(" byte 13  "); // prints byte 12 and byte 13 for debugging        float v = (analogChannelData * 3.25) / 10.24; float tempC = (v - 50); // converts raw A/D signal to deg C        float tempF = (tempC * 9 / 5) + 33; Serial.print(tempF);Serial.println("  Temp F  ");Serial.println("");  // converts C to F and prints it.33 upper sensor calibrate        writeNumber(file, tempF);                  // add value for tempF of pin(pinNum) to line of data         writeString(file, " , ");      // comma to separate readings for export to excel        lcd.setCursor(0, s);    // put the LCD cursor to row2 , column0  to start temp display line on LCD         if (tempF < 100 && tempF > 0)        // puts a '0' before 10-99 to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        if (tempF < 10 && tempF >= 0)        // puts a '0' before single digits to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        lcd.print(int (tempF) );         // print tempF1                int analogChannelData2 = (packet <<8) | packet;  // reads byte 14, shifts it over 8 bits, and appends byte 15 to it to form the raw data variable from the A/D converter reading        Serial.print(analogChannelData2);Serial.println(" TMP36 2 reading ");Serial.println("");  // prints raw A/D readingfor debugging        Serial.print(packet, HEX);Serial.print(" byte 14  ");Serial.print(packet, HEX); Serial.print(" byte 15  "); // prints byte 14 and byte 15 for debugging        float v2 = (analogChannelData2 * 3.25) / 10.24; float tempC2 = (v2 - 50); // converts raw A/D signal to deg C        float tempF2 = (tempC2 * 9 / 5) + 35; Serial.print(tempF2);Serial.println("  Temp F 2 ");Serial.println("");  // converts C to F and prints it.35 for sensor calibration upper        writeNumber(file, tempF2);                  // add value for tempF of pin(pinNum) to line of data         writeString(file, " , ");      // comma to separate readings for export to excel        lcd.setCursor(5, s);    // put the LCD cursor to row2 , column4  for temp display line on LCD         if (tempF2 < 100 && tempF2 > 0)        // puts a '0' before 10-99 to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        if (tempF2 < 10 && tempF2 >= 0)        // puts a '0' before single digits to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        lcd.print(int (tempF2));         // print tempF2                int analogChannelData3 = (packet <<8) | packet;  // reads byte 16, shifts it over 8 bits, and appends byte 17 to it to form the raw data variable from the A/D converter reading        Serial.print(analogChannelData3);Serial.println(" TMP36 3 reading ");Serial.println("");  // prints raw A/D readingfor debugging        Serial.print(packet, HEX);Serial.print(" byte 16  ");Serial.print(packet, HEX); Serial.print(" byte 17  "); // prints byte 16 and byte 17 for debugging        float v3 = (analogChannelData3 * 3.25) / 10.24; float tempC3 = (v3 - 50); // converts raw A/D signal to deg C        float tempF3 = (tempC3 * 9 / 5) + 33; Serial.print(tempF3);Serial.println("  Temp F 3 ");Serial.println("");  // converts C to F and prints it. 33 for sensor calibration upper        writeNumber(file, tempF3);                  // add value for tempF of pin(pinNum) to line of data         writeString(file, " , ");      // comma to separate readings for export to excel        lcd.setCursor(15, s);    // put the LCD cursor to row2 , column8  for display line on LCD         if (tempF3 < 100 && tempF3 > 0)        // puts a '0' before 10-99 to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        if (tempF3 < 10 && tempF3 >= 0)        // puts anot '0' before single digits to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        lcd.print(int (tempF3) );         // print tempF3               int analogChannelData4 = (packet <<8) | packet;  // reads byte 18, shifts it over 8 bits, and appends byte 19 to it to form the raw data variable from the A/D converter reading        Serial.print(analogChannelData4);Serial.println(" TMP36 4 reading ");Serial.println("");  // prints raw A/D readingfor debugging        Serial.print(packet, HEX);Serial.print(" byte 18  ");Serial.print(packet, HEX); Serial.print(" byte 19  "); // prints byte 18 and byte 19 for debugging        float v4 = (analogChannelData4 * 3.25) / 10.24; float tempC4 = (v4 - 50); // converts raw A/D signal to deg C        float tempF4 = (tempC4 * 9 / 5) + 33; Serial.print(tempF4);Serial.println("  Temp F 4 ");Serial.println("");  // converts C to F and prints it. 33 to calbrate sensor upper        writeNumber(file, tempF4);                  // add value for tempF of pin(pinNum) to line of data         writeString(file, " , ");      // comma to separate readings for export to excel        lcd.setCursor(10, s);    // put the LCD cursor to row2 , column8  for display line on LCD         if (tempF4 < 100 && tempF4 > 0)        // puts a '0' before 10-99 to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        if (tempF4 < 10 && tempF4 >= 0)        // puts a '0' before single digits to preserve format on LCD, allows for - sign display      {                              //        lcd.print("0");             //       }                            //        lcd.print(int (tempF4) );         // print tempF4                for(int i=0;i<4;i++) {        // change middle number to number of sensors?          if ((analogChannelData >> i) & 1) {            analogSamples[i] = (packet[analogSampleIndex] << 8) | packet[analogSampleIndex+1];            analogSampleIndex += 2;          } else {            analogSamples[i] = -1;          }        }      }    }      }} void printPacket(int l) {  for(int i=0;i < l;i++) {    if (packet[i] < 0xF) {      // if the packet value is HEX F or lower      Serial.print(0);         //print leading zero for single digit values    }    Serial.print(packet[i], HEX);    Serial.print(" ");  }  Serial.println(" new string ");Serial.println("");}int readByte() {    while (true) {      if (Serial.available() > 0) {      return Serial.read();    }  }} void loop(void) {  int pinNum = 1;      // variable to determine which sensor value is read.  int pinNumMAX = 3;    // variable to determine how many temperature sensors are in the stream    Serial.print(linecount); Serial.print(" start ");    // serial output for debugging      for ( dataLine = 0; dataLine < 30; dataLine ++) {         // larger number (divided by PinNumMAX) determines how many lines of data per WRITExx.txt file.        readPacket();    lcd.setCursor(14, 3);           //Position cursor for linecount     lcd.print(linecount);          // put linecount on LCD        pinNum = pinNum + 1;                       // advances to next pin in line of data    if (pinNum >=pinNumMAX)                    // check to see if pin number is at the end - ' if ' it is, run the following. If not, skips down to delay (1000) {}    {      pinNum = 1;                              // reset pinNum to get ready for new line of data      Serial.println(" ");                    // puts space in when debugging                                          Serial.print(linecount); Serial.print("= linecount  ");  // serial print for debugging   /*   DateTime now = RTC.now();               // Read RTC      Serial.print("TEST RTC ");      Serial.print(now.hour(), DEC);      Serial.print(":");      Serial.print(now.minute(), DEC);        // Gets minute from RTC       Serial.print(":");                      // puts the ":" between the minute and second      Serial.print(now.second(), DEC);      //Gets second from RTC - for debugging      Serial.println("   ");                  // space to format serial table better      lcd.setCursor(12, 0);                  // shows time on top right of LCD      lcd.print(now.hour(), DEC); lcd.print(":");    // displays current hour on LCD      if ((now.minute()) < 10)        // puts a '0' before single digits to preserve format on LCD      {                              //        lcd.print("0");             //       }                            //      lcd.print(now.minute(), DEC); lcd.print(":");    // displays current minute on LCD      if ((now.second()) < 10)        // puts a '0' before single digits to preserve format on LCD      {                              //        lcd.print("0");             //      }                            //      lcd.print(now.second(), DEC);     // display seconds on LCD          writeNumber(file, now.hour());     // timestamp hour      writeString(file, ":");            // format time with "  :  "      writeNumber(file, now.minute());   // timestamp minute      writeString(file, ":");            // format time with "  :  "      writeNumber(file, now.second());   // timestamp second  */      lcd.setCursor(12, 3);    // put the LCD cursor to row4 , column12        lcd.print("L=");         // print L for linecount.      writeCRLF(file);                        // goes to new line in text data file      linecount++;                            // adavances linecount for serial debugging and LCD  */    }                  delay (1000);                         // delay to adjust overall sample rate  }    file.close();                           // close file and force write of all data to the SD card  Serial.println("Done");                 // for debugging  char name[] = "WRITE00.TXT";           // create a new file for next batch of data  for (uint8_t i = 0; i < 100; i++) {    // will only do 100 SD file writes 5/17/10    name = i/10 + '0';                // the "char name" [fifth digit] = i/10 followed by a printed " 0 "    name = i%10 + '0';                // the "char name" [sixth digit] = i % (what?) followed by a " 0 "    if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;  }  if (!file.isOpen()) error ("file.create");  Serial.print("Writing to: ");  Serial.println(name);  lcd.setCursor(0,3);  lcd.print(name); }`

Serial Window NICE and tidy- SD card working great. LCD monitor also working *perfectly*.(no pics, however. I can get one if desired.) Missing lines of data are OK - I put the remote XBee down to a transmission every 3 seconds back when I thought it was a RAM issue. The program is sampling before there is data in the buffer. EZ fix.

Well, down to the RTC, RTC library or the Wire library. I will most certainly post results. I do need the timestamp, and would like not to have to set the time every use/reset!
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Logger Shield and Negative Numbers

Looks like memory overwrite problems.
You have:
Code: Select all | TOGGLE FULL SIZE
`   int packet;`

But appear to store 20 values:

Initial 7E, two for length, 16 for data, and one for check sum for a total of twenty value.

You should put a test in to make sure
Code: Select all | TOGGLE FULL SIZE
`int dataLength = (packet << 8) | packet;`

is not too large for the array packet[]. You need to check/test all array indexes for range.
fat16lib

Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: Logger Shield and Negative Numbers

That isnt 20 bytes- packet - packet ?
Livin' , learnin' , lovin' and laffin'. Thanks for the help! Volkemon

Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA
{"ft_lang_label":"__label__en","ft_lang_prob":0.74295694,"math_prob":0.8984393,"size":2277,"snap":"2021-04-2021-17","text_gpt3_token_len":610,"char_repetition_ratio":0.12934448,"word_repetition_ratio":0.13089006,"special_character_ratio":0.29776022,"punctuation_ratio":0.18354431,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9501156,"pos_list":[0,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],"im_url_duplicate_count":[null,1,null,1,null,9,null,9,null,9,null,9,null,null,null,9,null,9,null,9,null,9,null,1,null,1,null,9,null,9,null,1,null,1,null,9,null,9,null,1,null,1,null,9,null,9,null,1,null,1,null,9,null,9,null,9,null,9,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-01-25T14:44:30Z\",\"WARC-Record-ID\":\"<urn:uuid:a121fae0-e493-4006-814d-d9e81a44f7d2>\",\"Content-Length\":\"116112\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:ec86b147-c378-45d7-875e-bda986949739>\",\"WARC-Concurrent-To\":\"<urn:uuid:30d63aa3-2ff5-4fe1-9747-821524b0ecbd>\",\"WARC-IP-Address\":\"34.200.112.132\",\"WARC-Target-URI\":\"https://forums.adafruit.com/viewtopic.php?f=24&t=16103\",\"WARC-Payload-Digest\":\"sha1:CN6ELRGVAV37OBIHC64OLSLS7BLZO4FV\",\"WARC-Block-Digest\":\"sha1:NZMR26B2FXD6O7IQ6YYT2GECWRSWQL65\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-04/CC-MAIN-2021-04_segments_1610703581888.64_warc_CC-MAIN-20210125123120-20210125153120-00414.warc.gz\"}"}