Go Down

Topic: I'm having trouble concatenating with Uno R3 (Read 220 times) previous topic - next topic

sdingman

I'm trying to get pin 4 to go High when the % reading goes above 95%, among other things. I'm not getting the result that I though that I should. I suspect that there may be an issue at the point where I try to concatenate 'a' character into the 'batteryLevel' String. I am very green at this. Any suggestions would be appreciated.

Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial myBatteryMonitor(2, 3); // RX, TX define the pins to use
const int loadTransfer = 4; //output Pin to select Grid or Inverter
const int invPower=5;       //output Pin to turn inverter on
const int invOnInd=6;       //input Pin to verify that inverter power is available.
int strBatteryLevel = 0;    //Create the Integer 'strBatteryLevel' and set it equal to 0.
                            //'strBatteryLevel' will be used to count Characters.
String batteryLevel;        //'batteryLevel' is a String to store the Concatenated values of 'a'
String relayToggle;
String loadTransferToggle;  //used to display the high or low of pin 5
String inverterToggle;      //used to display the high or low of pin 4
int count;
void setup(){
Serial.begin(9600); // speed to talk to the computer
myBatteryMonitor.begin(2400); // speed to read the Battery Monitor
pinMode(loadTransfer, OUTPUT);//Pin 4, Output to switch main power relay
pinMode(invPower, OUTPUT);   //Pin 5, Output to switch Inverter on
pinMode(invOnInd, INPUT);    //Pin 6, Input verifying Inverter is on and ready
int count = 0;           
String relayToggle = "ON";
}
void loop(){
  if(myBatteryMonitor.available() > 0){ //If there is a signal coming in
    char a = myBatteryMonitor.read();   //place that character into character variable 'a'.
    if(strBatteryLevel>0){      //'strBatteryLevel' is a character counter when a=%
      strBatteryLevel++;        //increment the character counter
        if(a=='0' | a=='='){}   //if the character is a 0 or an =, then discard the character.
      else{batteryLevel+=a;}    // otherwise, concatenate 'a' into 'batteryLevel' String.
    }
    if(strBatteryLevel==5){     //if the number of characters in 'strBatteryLevel' are counted up to 5 characters
      strBatteryLevel=0;        //Reset the count of characters stored in 'strBatteryLevel' to 0
      batteryLevel="";          //The 'batteryLevel' string variable is set to be empty.
      }
    if(a =='%') {               //If the character coming in is a '%' symbol
    count++;                    //Increment the count integer if a=%.
    strBatteryLevel++;          //Increment the strBatteryLevel integer if a=%.
    }
    if(count >=1){              //If the 'count' integer is 1 or more
      count = 0;                //Reset the 'count' integer to 0
      Serial.println();         //Insert a carriage return
      Serial.println(batteryLevel + batteryLevel.toInt() + " " + inverterToggle + " " + loadTransferToggle);
      }
    Serial.write(a);
    if(digitalRead(invOnInd) == HIGH){        // if((digitalRead(invOnInd) == HIGH)==1)
      if(batteryLevel.toInt()>94){
        digitalWrite(loadTransfer,HIGH);
        loadTransferToggle = "Load Transfer: HIGH";
      }
    }
    else{
      if(batteryLevel.toInt()<92){
        digitalWrite(loadTransfer,LOW);
        loadTransferToggle = "Load Transfer: LOW";
        digitalWrite(invPower, LOW);
        inverterToggle = "Inverter: LOW";
      }
      if(batteryLevel.toInt()>94){
        digitalWrite(invPower,HIGH);
        inverterToggle = "Inverter: HIGH";
      }
    }
  }
 }

Robin2

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

Can you give an example of the data that comes from your battery monitor device?
And post a link to the datasheet for the battery monitor.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

sdingman

Thanks for your response. I'm using 'Cool Term' because I can start and stop the reading of data and its easy to just grab a few lines. The top row is my attempt to few the stat of 'batteryLeval', where I currently am only receiving a 0. The Inverter: LOW is Pin 4, and Load Transfer: LOW is pin 5. These readings are the current output of what I am receiving from a Battery Monitor.



0 Inverter: LOW Load Transfer: LOW
%=093,W=71.4,DSC=10.0,DSE=29.8,PW=2FF,V=13.4,FV=13.4,V2=00.0,A=05.3,FA=04.9,PW=2FF,AH=-27.0,
0 Inverter: LOW Load Transfer: LOW
%=093,W=71.4,DSC=10.0,DSE=29.8,PW=2FF,V=13.4,FV=13.4,V2=00.0,A=05.3,FA=04.9,PW=2FF,AH=-27.0,
0 Inverter: LOW Load Transfer: LOW
%=093,W=71.4,DSC=10.0,DSE=29.8,PW=2FF,V=13.4,FV=13.4,V2=00.0,A=05.3,FA=04.9,PW=2FF,AH=-27.0,
0 Inverter: LOW Load T

Robin2

#3
May 19, 2017, 06:44 pm Last Edit: May 19, 2017, 06:45 pm by Robin2
Is this all one message
%=093,W=71.4,DSC=10.0,DSE=29.8,PW=2FF,V=13.4,FV=13.4,V2=00.0,A=05.3,FA=04.9,PW=2FF,AH=-27.0,
0 Inverter: LOW Load Transfer: LOW


I ask, because the first of the lines I have copied ends with a comma

I suggest you try reading the data with the second example in Serial Input Basics but change the end-marker to '%'. It means you will miss the first message but get all the rest. And change numChars to a number big enough to hold the entire message plus 2 chars.

Report if that works and then we can see what else is needed.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

sdingman

Robin2,
First, The original message coming out of my battery monitor has no start or end character. My code searches for the '%' and inserts a line feed, making it look like the message starts with a %.

The '0 Inverter: LOW Load Transfer: LOW', is also generated by the sketch, and is not part of the streaming data coming out of the battery monitor. I only put it in there to help me troubleshoot.

There is another issue with using numChars, sometimes the message is longer. At times, there are extra pieces of data coming out, so if I try to set the message length, it will occasionally be wrong. So there must be a way to do what I'm trying to do without a definite number of characters being known.

I'm not to worried about a comma at the end.

sdingman

How would I deal with arbitrary message length. I found an example of a cycle with extra data.

%=095,W=-73.8,DSC=10.2,DSE=30.0,PW=0FF,X=28A,V=12.9,FV=12.9,V2=00.0,A=-05.7,FA=-06.3,PW=0FF,AH=-19.3,

There is 98 characters in this sample.

A shorter sample is:

%=095,W=-73.8,DSC=10.2,DSE=30.0,PW=0FF,V=12.9,FV=12.9,V2=00.0,A=-06.1,FA=-06.3,PW=0FF,AH=-19.3,

There are 92 characters in this sample. What can I do about this?

BulldogLowell

There are 92 characters in this sample. What can I do about this?
if you are trying to capture just certain fragments of the full message, you can just toss everything that isn't between the substrings...

from that example string, what values do you want?


Robin2

Robin2,
First, The original message coming out of my battery monitor has no start or end character. My code searches for the '%' and inserts a line feed, making it look like the message starts with a %.
Did you try what I suggested? What happened?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

holmes4

Code: [Select]
       if(a=='0' | a=='='){}   //if the character is a 0 or an =, then discard the character.

Wrong!

Mark

holmes4

Quote
%=095,W=-73.8,DSC=10.2,DSE=30.0,PW=0FF,V=12.9,FV=12.9,V2=00.0,A=-06.1,FA=-06.3,PW=0FF,AH=-19.3,

There are 92 characters in this sample. What can I do about this?
Stop being stupid - The comma's are the start/end's your looking for!

Mark

BulldogLowell

#10
May 20, 2017, 03:03 am Last Edit: May 20, 2017, 03:04 am by BulldogLowell
Stop being stupid - The comma's are the start/end's your looking for!

Mark
You are a true model of pedagogy; this is a place of learning and sharing.  You really should be ashamed of yourself for comments like that, that imperious tone is the antithesis of what this forum is all about. 

Was there ever a time in your life when you didn't know all this? 

Only the pompous confuse knowledge for intelligence, trading insults for hubris.

Robin2

The comma's are the start/end's your looking for!
I think the OP is only interested in the %= value and as there seems to be only one % char in the message that is why I suggested he use it as the end-marker.

I suspect that using a comma as an end-marker would be unnecessarily fine-grained.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

AWOL

Code: [Select]
       if(a=='0' | a=='='){}   //if the character is a 0 or an =, then discard the character.

Wrong!

Mark
Is it?
Or is it simply expressed in a way you hadn't considered?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

sdingman

Gentlemen,
Thank you so much for all of your kind and generous input. Upon further review, I found that my method of concatenation was not the problem after all. I found that my String batteryLevel actually needed to be an integer in order for the logical if statements to work properly. So I just had to create a global Integer variable, 'batteryperc' and set it equal to 'batteryLevel'

batteryPerc = batteryLevel.toInt();

Now all is well in battery monitor land.

Go Up