Go Down

Topic: grap first char in array value and change it to hex (Read 292 times) previous topic - next topic

MaxG

A serial input massaged to what I want it to be, can occasionally result in:

Code: [Select]
53.0,-12.3,-89,78,31.81,0,2
53.0,-12.1,-89,78,31.75,0,3
53.0,-12.0,-89,78,31.75,0,4
?3.0,-12.3,-89,78,31.75,0,5
53.0,-12.2,-89,78,31.75,0,6
53.0,-12.2,-89,78,31.75,0,7


The code for the first three values is:

Code: [Select]

char recordOut[80];        // one record out from BMS
int arrayElements = 12;                 // number of array values
char *arrValues[arrayElements];         // array holding values
...
         for (int i = 0; i <= 3; i++) {          // VLT, AMP, AHR, SOC
            strcat(recordOut, arrValues[i]);      // add value
            strcat(recordOut, ",");               // add delimiter
          }


My question: How do get I get the first char in arrValues[0]; check if it is other than 5 and if so, display either the first char in arrValues[0] or all of them as HEX?

Pseudo code:

Code: [Select]

for (int i = 0; i <= 3; i++) {          // VLT, AMP, AHR, SOC
  if (arrValue[0].firstChar != 5 {
    strcat(recordOut, hex(arrValue[0].firstChar()));
    strcat(recordOut, ",");               // add delimiter
  }
  strcat(recordOut, arrValues[i]);      // add value
  strcat(recordOut, ",");               // add delimiter
}



So that the result is:
Code: [Select]

53.0,-12.3,-89,78,31.81,0,2
53.0,-12.1,-89,78,31.75,0,3
53.0,-12.0,-89,78,31.75,0,4
04, ?3.0,-12.3,-89,78,31.75,0,5
53.0,-12.2,-89,78,31.75,0,6
53.0,-12.2,-89,78,31.75,0,7



Any hints appreciated; thanks.
Mainly using UNOs. Everything needs to be defined.

J-M-L

snippet don't help....

what's the type of arrValue?
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

MaxG

Mainly using UNOs. Everything needs to be defined.

J-M-L

oops... modified original post...
that helps :)

so if you have char *arrValues[arrayElements]; then the first character of the nth entry is (*arrValues[n])

arrValues[n] is a pointer to a list of characters, and *pointer  is the first byte in memory pointed by pointer, so will be your first char
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

MaxG

Thanks... modified code, like so

Code: [Select]

          for (int i = 0; i <= 3; i++) {          // VLT, AMP, AHR, SOC

            if (i == 0) {
              if (*arrValues[0] != '5') {
                Serial.println(*arrValues[0], HEX);
                strcat(recordOut, *arrValues[0]);      // add value
                strcat(recordOut, ",");               // add delimiter
              }
            }
            strcat(recordOut, arrValues[i]);      // add value
            strcat(recordOut, ",");               // add delimiter
          }


Serial.print() along works:

Code: [Select]
53.0,-15.1,-98,76,31.56,0,44
1
?3.0,-15.0,-98,76,31.56,0,45
53.0,-15.1,-98,76,31.56,0,0


However, strcat() after the Serial.print() does not work.

Yes, I am deficient in C string and pointers :(
Mainly using UNOs. Everything needs to be defined.

J-M-L

Can you try to explain in plain English what you think your code is doing? (Curious about the strcat(recordOut, *arrValues[0]);  especially but all the rest as well)
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

MaxG

In simple terms, the program reads serial data from a battery monitor system, grabs what is of interest, and then sends it out on Ethernet via MQTT.

I have three monitors at present (prototypes), one on an UNO with RTC no Ethernet; one on a MEGA with RTC and Ethernet and MQTT, and the latest (this) on UNO no RTC, no datum, no NTP, just in, massage, and out.

Interestingly enough, this initial post came about when I realised that every so often (no pattern) the first char of the recordOut has a hex 01 in it; why I wanted to capture this and simply replace it with the previous value. The other two prototypes do not show this issue. I eventually want to extend the code to run a simple check sum over the recordOut; or compare previous record with current, and only send a MQTT update when there has been a change, rather than every second as it is at present.

I am currently starting from scratch reading up on pointers, arrays, char, char*, *char, and what not. I want the code to be lean, hence no use of string functions... and it had to be lean to fit on an UNO. MQTT takes a buffer contents (which is a char array), which required me to enter the C world more in-depth, but I really struggle with type conversions (not even able to decide, whether I need to or or not.

I have attached the code, as it is too long to be posted.
Mainly using UNOs. Everything needs to be defined.

J-M-L

just had a quick look at your code and this part will possibly overflow
Code: [Select]
      if (recordInByteCount < RECORD_IN_ARRAY_SIZE) {
        // select the bytes we want = digits and .,-
        if (isdigit(inByte) || inByte == '.' || inByte == ',' || inByte == '-') {
          recordIn[recordInByteCount] = inByte;   // add byte received to array
          recordInByteCount++;                    // increment byte counter
          recordIn[recordInByteCount] = '\0';     // add \o to end of array
        }
      }
indeed RECORD_IN_ARRAY_SIZE is 120. imagine your are already at 119 so the size test works and imagine you receive a '6', it's a digit so you add it to the array recordIn[119] = '6'; then you increment recordInByteCount to 120 and you write a '\0' in recordIn[120]; which is an overflow.

Same here, this overflows as well:
Code: [Select]
          int arrayElements = 12;                 // number of array values
          char *arrValues[arrayElements];         // array holding values

          arrValues[0] = strtok(recordIn, ",");   // get first token

          for (int j = 1; j <=arrayElements; j++) {
            arrValues[j] = strtok(NULL, ",");     // walk through all other tokens
          }
when j reaches arrayElements (12) you write into arrValues[12] which is not allocated in your array (arrValues indexes go from 0 to 11)

I'd start investigating those overflow - the first one might happen only from time to time but the second one every time.
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

MaxG

Thank you for looking into my code; much appreciated...
As I understand the recordIn[] is never longer than 120, but I can certainly add a few bytes...
The second one, is clearly an error on my behalf; I thought being a smart-arse counting form 1 to 12 instead of 0 to 11 is a good idea; but it isn't, as you rightly said, I do stuff with 12 which does not exist.
Mainly using UNOs. Everything needs to be defined.

J-M-L

Check after fixing this if you still have challenges.
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

MaxG

Thanks, I made the suggested changes, and reverted them back after testing revealed that it made no difference (or the problem is not sitting there.

However, I further cleaned up the the code, and removed the testing for the first byte, and the 'faulty' byte I was looking for was all of a sudden gone. So, some of the deleted lines seem to contain the error; but I think shifting the odd variable declaration further up may have done it.

I have attached the cleaned-up file... the odd rename for clarity... for comparison (if you feel like it).

I have also read and applied the C style guide to my code; which I agree with -- yes, an overkill for single simple Arduino projects, but I like to do it right the first time. (and never have to worry about it).
Mainly using UNOs. Everything needs to be defined.

PaulMurrayCbr

so if you have char *arrValues[arrayElements]; then the first character of the nth entry is (*arrValues[n])
IMO: In this situation, just using array syntax is clearer:
arrValues[n][0]

It will compile down to the same thing.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

Go Up