Working with a string.

Hello Everyone,

Maybe someone can help save me a some time and sleepless nights. I am using an Arduino nano.

I have a string that contains F01050D1. This is data from a sensor. It breaks down like this.
The first letter (F) tells me what sensor. I have no further use for this letter. The following
5 numbers are what the sensor is reporting (01050). The next 2 (D1) tell me how many decimal places are
in the five numbers that the sensor has reported. That will be a 0,1,or 2. In the case 0105.0 is reported.
I want to display this as 105 on a led display.

Sounds simple but I have not been able to extract the 105 correctly.

Thanks in advance,

IslaPete

Did you try D0?

I have reached this point. I can display the raw data.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
String fwd; // String for forward power
String refl; // String for reflected power
String swr; // String for SWR display
char test[4];

//Initialise the LCD
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

void setup()
{
//Define the LCD as 20 column by 4 rows
lcd.begin (20,4);

//Switch on the backlight
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);

// Setup base display
lcd.setCursor(0, 0); // Set the cursor on the first column and the first row.
lcd.print(“FWD PEAK W”);
lcd.setCursor(0, 1); //Set the cursor on the first column and the second row (counting starts at 0!).
lcd.print(“FWD AVG W”);
lcd.setCursor(0, 2); //Set the cursor on the first column and the third row (counting starts at 0!).
lcd.print(“REFL W”);
lcd.setCursor(0, 3); //Set the cursor on the first column and the forth row (counting starts at 0!).
lcd.print(“SWR 1.1:1”);

Serial.begin(9600);

}

void loop(){
{delay(500);
Serial.write(“F”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
fwd = Serial.readString();
lcd.setCursor(10, 0);
lcd.print(fwd);
lcd.setCursor(19, 0);
lcd.print(“W”);}

{ Serial.write(‘N’);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
Serial.write(‘F’);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
fwd = Serial.readString();
lcd.setCursor(10, 1);
lcd.print(fwd);
lcd.setCursor(19, 0);
lcd.print(“W”);
Serial.write(‘N’);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’); }

{Serial.write(‘R’);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
refl = Serial.readString();
lcd.setCursor(10, 2);
lcd.print(refl);
lcd.setCursor(19, 2);
lcd.print(“W”);}

{Serial.write(‘S’);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
swr = Serial.readString();
lcd.setCursor(12, 3);
lcd.print(swr);
lcd.setCursor(18, 3);
lcd.print(":1");}

}

I have changed some of the display printing.

This is my last Sketch. Sorry for my early version.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
String fwd; // String for forward power
String refl; // String for reflected power
String swr; // String for SWR display
char test[4];

//Initialise the LCD
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

void setup()
{
//Define the LCD as 20 column by 4 rows
lcd.begin (20,4);

//Switch on the backlight
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);

// Setup base display
lcd.setCursor(0, 0); // Set the cursor on the first column and the first row.
lcd.print(“FWD PEAK W”);
lcd.setCursor(0, 1); //Set the cursor on the first column and the second row (counting starts at 0!).
lcd.print(“FWD AVG W”);
lcd.setCursor(0, 2); //Set the cursor on the first column and the third row (counting starts at 0!).
lcd.print(“REFL W”);
lcd.setCursor(0, 3); //Set the cursor on the first column and the forth row (counting starts at 0!).
lcd.print(“SWR :1”);

Serial.begin(9600);

}

void loop(){
{
Serial.write(“F”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
fwd = Serial.readString();
lcd.setCursor(10, 0);
lcd.print(fwd);}

{ Serial.write(“N”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
Serial.write(“F”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
fwd = Serial.readString();
lcd.setCursor(10, 1);
lcd.print(fwd);
Serial.write(“N”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’); }

{Serial.write(“R”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
refl = Serial.readString();
lcd.setCursor(10, 2);
lcd.print(refl);}

{Serial.write(“S”);
while (!Serial.available() > 0)
Serial.readStringUntil(’;’);
swr = Serial.readString();
lcd.setCursor(12, 3);
lcd.print(swr);}

}

Please edit your posts to add code tags, as described in the "How to use this forum" post.

You don't need to use Strings for this and should not, because on a standard, AVR-based Arduino, they cause memory problems and unpredictable program crashes.

Instead, use C-strings (zero terminated character arrays). There is an extensive library of small, reliable routines that allow to dissect the character stream, convert ASCII characters into numbers, etc. You need that to handle the multiplier and value stream separately.

Google "string.h reference C/C++" for extensive tutorials.

Looks like I may be able to do it this way:

String msg = "F12345D2";

String fwd = msg.substring(1, 6);

String decimal = msg.substring(7);

This gives me fwd = 12345 and decimal = 2.

Now I need to change these String to intergers and a little math?

Keith

Did you even try the suggestion in reply#1? Or read the request for formatting in reply#5?

Please edit your posts to add code tags, after reading "How to use this forum".

I am very very new to this. I looked at DO, but for me it was more than my knowledge could handle.
I was able to get what I needed with 2 lines of code.

I did not go back and format the sketch because it had nothing to do with my question. The String could have come from any number of sketches.

I'm sorry if I did not follow protocol. As I said I am very new to this and doing the best I can. I will try and do better in the future.

islapete:
As I said I am very new to this and doing the best I can. I will try and do better in the future.

To that end - How to use this forum.

"The next 2 (D1) tell me how many decimal places are
in the five numbers that the sensor has reported. That will be a 0,1,or 2. In the case 0105.0 is reported."

This tells me you do understand what the 'D1' does. So why is is so hard to understand what a 'D0' does? It's even simpler than your 2 lines of code.

islapete:
I have a string that contains F01050D1. This is data from a sensor. It breaks down like this.
The first letter (F) tells me what sensor. I have no further use for this letter. The following
5 numbers are what the sensor is reporting (01050). The next 2 (D1) tell me how many decimal places are
in the five numbers that the sensor has reported. That will be a 0,1,or 2. In the case 0105.0 is reported.
I want to display this as 105 on a led display.

Sounds simple but I have not been able to extract the 105 correctly.

1. Check that you have received F and then start to receive/store the remaining 7 characters.

byte n = mySerial.available();
if (n !=0 )
{
    char x = mySerial.read();
    if(x == 'F')     
    {
       flag = true;           //F is found
    }
}

2. Receive and save the remaining 7 characters (01050D1)

byte n = mySerial.available();
if(flag == true)
{
    if ( n==7)
    {
         for(int i=0; i<7; i++)
         {
              myData[i] = mySerial.read();   //
         }
          myData[5] = '\0'            //adding null character
          int x = atoi(myData);      // x holds the integer value 1050
          //-----------------------
          byte y = myData[6] - '0';          //y holds 0x00, or 0x01, or 0x02
          float z = (x/(pow(10, y));               //
          Serial.print(z, y)                      //shows: 105.0
    }
}

3. Combine codes of Step-1 and Step-2 to create your receiver sketch.

Receiver Codes:

#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);   //SRX = DPin-2, STX = DPin-3
bool flag = false;

char myData[10];
void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop()
{
  byte n = mySerial.available();
  if (flag == false)
  {
    if (n != 0 )
    {
      char x = mySerial.read();
      if (x == 'F')
      {
        flag = true;           //F is found
      }
    }
  }
  else
  {
    if ( n == 7)
    {
      for (int i = 0; i < 7; i++)
      {
        myData[i] = mySerial.read();   //
      }
      myData[5] = '\0';            //adding null character
      int x = atoi(myData);      // x holds the integer value 1050
      //Serial.println(x, DEC);
      //-----------------------
      byte y = myData[6] - '0';    //y holds 0x00, or 0x01, or 0x02
      float z = (x / pow(10, y));  //
      Serial.println(z, y);       //Serial Monitor shows: 105.0
      flag = false;
    }
  }
}

Simulated Sensor Codes:

#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);   //SRX = DPin-2, STX = DPin-3
char myData[] = "F01050D1";

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop()
{
  mySerial.write(myData, sizeof(myData));
  delay(2000);
}

smFx.png

smFx.png