Want to combine 2 codes together

Hi,

This is my code:

const int relayPin = 5; 

int state;             
int flag;              


void setup()
{
  pinMode(relayPin, OUTPUT);  
    Serial.begin(9600);         
}

void loop()
{
    if(Serial.available() > 0){     
      state = Serial.read();    
    } 
  
  
 
    if (state == 'W') {
      if (flag==0){  
         digitalWrite(relayPin, HIGH); 
         flag=1;
      }
      else if (flag==1){
         digitalWrite(relayPin, LOW); 
         flag=0;
      }
      state='n';
    } 
    delay(200); 
}

When i add this one:

    if (Serial.available()) {
      byte c = Serial.read ();
      delay(3);
      // If a measurement is required, measure data and send it back
      if (c == 't'){

           int t = (int)dht.readTemperature();
           Serial.println(String(t) + "c");
}

           if (c == 'h'){
           
           int h = (int)dht.readHumidity();
           Serial.println(String(h) + "%");

the first code line (fan commend)work fine without the sec code. after i add the sec code is didn't work at all (uploded to my arduino, but don't work).

I newbie, and because that - don't know how to combine the both codes lines to work together.

i think the problem is: to store the data from serial - conflict?!

Delta_G:
Since you already have a section of code reading from serial, just add that one if test to it and leave out the part that reads serial in the second code. Of course change the name of the variable to match what's in the other code.

Like this?

const int relayPin = 5; 

int state;             
int flag;              


void setup()
{
 pinMode(relayPin, OUTPUT);  
   Serial.begin(9600);         
}

void loop()
{
   if(Serial.available() > 0){     
     state = Serial.read();    
   } 
 
 

   if (state == 'W') {
     if (flag==0){  
        digitalWrite(relayPin, HIGH); 
        flag=1;
     }
     else if (flag==1){
        digitalWrite(relayPin, LOW); 
        flag=0;
     }
        
    else if (state == 't'){

          int t = (int)dht.readTemperature();
          Serial.println(String(t) + "c");
}

          else if (state == 'h'){
          
          int h = (int)dht.readHumidity();
          Serial.println(String(h) + "%"); 
          }
     state='n';
   } 
   delay(200); 
}

and thanks :slight_smile:

const int relayPin = 5;

int state;             
int flag;             


void setup()
{
 pinMode(relayPin, OUTPUT); 
   Serial.begin(9600);         
}

void loop()
{
   if(Serial.available() > 0){     
     state = Serial.read();   
   }



   if (state == 'W') {
     if (flag==0){ 
        digitalWrite(relayPin, HIGH);
        flag=1;
     }
     else if (flag==1){
        digitalWrite(relayPin, LOW);
        flag=0;
     }
     state='n';
   }
   // delay(200); // I hate delays... worthless

     // If a measurement is required, measure data and send it back
     else if (state == 't'){

          int t = (int)dht.readTemperature();
          Serial.println(String(t) + "c");  /* Terrible idea. At first I did the same thing, it sure is easy to use Strings like this, but you don't understand memory fragmentation caused by using global Strings yet... It will come back and bite you in the butt later on if you use Strings like this... */ 
}

          else if (state == 'h'){
          
          int h = (int)dht.readHumidity();
          Serial.println(String(h) + "%");   // again... bad idea
 
}

Someone explain why using Strings like he is in global isn't a good idea.

Thomas499:

const int relayPin = 5;

int state;           
int flag;

void setup()
{
pinMode(relayPin, OUTPUT);
  Serial.begin(9600);       
}

void loop()
{
  if(Serial.available() > 0){   
    state = Serial.read(); 
  }

if (state == 'W') {
    if (flag==0){
        digitalWrite(relayPin, HIGH);
        flag=1;
    }
    else if (flag==1){
        digitalWrite(relayPin, LOW);
        flag=0;
    }
    state='n';
  }
  // delay(200); // I hate delays... worthless

// If a measurement is required, measure data and send it back
    else if (state == 't'){

int t = (int)dht.readTemperature();
          Serial.println(String(t) + "c");  /* Terrible idea. At first I did the same thing, it sure is easy to use Strings like this, but you don't understand memory fragmentation caused by using global Strings yet... It will come back and bite you in the butt later on if you use Strings like this... */
}

else if (state == 'h'){
         
          int h = (int)dht.readHumidity();
          Serial.println(String(h) + "%");  // again... bad idea

}




Someone explain why using Strings like he is in global isn't a good idea.

Thanks :slight_smile:

It's too bad that there is no Serial.printf method.
It would save an awful lot of time if there was.

Why don't you explain it?

I don't know how to explain fragmentation, i'm just learning about it myself, mostly from PaulS. I know Strings are evil, and whoever decided to use them in the libraries built in examples can go to H***. Would you like a working code that shows fragmentation causing a crash after a few seconds? Basically, you have heap and (need help what the other called?) one works from the top, the other works from the bottom. Lets say you have 100 memory. if you have a String that takes up 20, and add 1 to it, it looks for the next avalible free memory space to insert that into. So it puts 21 on top of the old 20, you can use the 20 if something can fit into it, but its unlikely it will exactly 20, lets say the next block is 15 so you'll have 5 memory left over in that whole which you can't use until the String is cleared or until something smaller than 5 is created, but remember, everytime you use that Global String to add or take away anything, this keeps happening, and sooner or later you will have a lot of fragmentation that even freeRam() will say is memory available, but even though it isnt being used it's a whole bunch of small patches that nothing large can fit in. By using arrays, this doesn't happen... That's my understanding anyway

And after 583 posts on these forums, you should know better than to post code inline without code tags.

You would think huh. I did a quick edit to make sure the code complied, when I paste it back in I forgot to re-include them.

Fragmentation

Imagine a open garage floor.

You place some object in the garage, followed by another of a different size and another and another. Pretty soon the the floor no longer has an open space for your next object yet oddly the are spaces between the current objects that if you could just move them around other you would be able to make space for the new one but all existing object are known to there owner by there current positions.

What do you do? Nothing since avery one of them in reference by there location or address.

Perhaps, but if it is not your object you'll start a fight and some will with that address will get into you object messing things up.

Very bad thing can happen!

Can you free up a couple closely spaced object giving enough space for the new object?

Sorry if that not entirely clear. Sitting i doctors office following surgery without pain meds.

Is fragmentation even a problem for something like:

serial.print(String(othervar)+"blah")?

Doesn't the String go out of scope as soon as the line is executed, so you're only in a problem if you're already very close to the memory limit? Or is there something more to this?

Not that I'm advocating putting away the stakes and holy water w/regards to String, not at all - I was just under the impression that that specific case didn't pose a fragmentation issue, since the String should go away as soon as that line is run....

One workaround is to declare a character array longer than the length of the longest message you expect to want to display, and then use that array as a place to build messages.

There is a beautiful example of that here: http://www.cplusplus.com/reference/cstdio/sprintf/
(Note: That will not work as an Arduino sketch, but the code inside the braces will work in an Arduino sketch if you substitute Serial.print for printf in line 9.)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
char buffer [50];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  Serial.println("[%s] is a string %d chars long\n",buffer,n);
  return 0;
}

error message

^

exit status 1
no matching function for call to 'HardwareSerial::println(const char [32], char [50], int&)'

I'm not use to printing int's like this, but I am interested in learning. What's wrong with the code that I modified based on what odometer said to do?

We don't get printf with Arduino which is that you are trying to use here.

Is there a reason, like hardware/memory limitations or is this something we can modify the arduino library to do?

I've never used sprintf before. I got it to work like this

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
char buffer [50];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  Serial.print("[%s] is a string %d chars long\n");
  Serial.print(buffer);
  Serial.println(n);
}

but I can't seem to figure out how to use sprintf to put it in one buffer

but I can't seem to figure out how to use sprintf to put it in one buffer

char pissAwayMemoryUselessly[80];
sprintf(pissAwayMemoryUselessly, "[%s] is a string %d chars long\n", buffer, n);
Serial.print(pissAwayMemoryUselessly);

There is NO benefit in doing this, though. NONE!

There is NO benefit in doing this, though. NONE!

char pissAwayMemoryUselessly[80];

I was trying to reuse the char buffer [50]; so that it added to buffer to use up the remaining free space in buffer. I thought the concept was to make a substitute String using array that you assigned the length of in advance. Yeah if you have to create another buffer, that seems like it would be a was of memory.

I was trying to reuse the char buffer [50]

I wouldn't recommend that. You could use something like:

char more[40];
sprintf(more, " is a string %d chars long\n", n);
strcat(buffer, more);
Serial.print(buffer);

but I still don't see any advantage. There is no real formatting going on.

unsigned long BeforeMethodTime=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  method1();
  method2();
  method3();
}

void loop() {
  // put your main code here, to run repeatedly:

}

void method1(){
  char buffer [50];
  int n, a=5, b=3;
  Serial.println(F("Method 1"));
  BeforeMethodTime=micros();
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  Serial.print("[%s] is a string %d chars long\n");
  Serial.print(buffer);
  Serial.print(n);
  Serial.print(F("Time taken in nano seconds was "));
  Serial.println(micros()-BeforeMethodTime); 
  Serial.print(F("FreeRam is "));
  Serial.println(freeRam());
  Serial.println();
}

void method2(){
  char buffer [50];
  int n, a=5, b=3;
  Serial.println(F("Method 2"));
  BeforeMethodTime=micros();
  char pissAwayMemoryUselessly[80];
  sprintf(pissAwayMemoryUselessly, "[%s] is a string %d chars long\n", buffer, n);
  Serial.print(pissAwayMemoryUselessly);
  Serial.print(F("Time taken in nano seconds was "));
  Serial.println(micros()-BeforeMethodTime); 
  Serial.print(F("FreeRam is "));
  Serial.println(freeRam());
  Serial.println();
  
}
void method3(){
  char buffer [50];
  int n, a=5, b=3;
  char more[40];
  Serial.println(F("Method 3"));
  BeforeMethodTime=micros();
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  sprintf(more, " is a string %d chars long\n", n);
  strcat(buffer, more);
  Serial.print(buffer);
  Serial.print(F("Time taken in nano seconds was "));
  Serial.println(micros()-BeforeMethodTime); 
  Serial.print(F("FreeRam is "));
  Serial.println(freeRam());
  Serial.println();
}
  int freeRam() {
  extern int __heap_start,*__brkval;
  int v;
  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval);  
}

Serial monitor Readout using the 3 methods.

Method 1
[%s] is a string %d chars long
5 plus 3 is 813Time taken in nano seconds was 22808
FreeRam is 1708

Method 2
[plus 3 is 8] is a string 0 chars long
Time taken in nano seconds was 72800
FreeRam is 1632

Method 3
5 plus 3 is 8 is a string 13 chars long
Time taken in nano seconds was 73840
FreeRam is 1664

There is NO benefit in doing this, though. NONE!

but I still don't see any advantage. There is no real formatting going on.

I may have messed up the code somewhere, but method3 seems to be the only one that worked correctly.

None of the times are in nanoseconds.

Method 1 is junk. It does not have any code to resolve the %s and %d format specifiers in the Serial.print() call.

Method 2 is pointless. You need to populate buffer before you use it to populate pissAwayMemoryUselessly.

Delta_G:

Serial.println("[%s] is a string %d chars long\n",buffer,n);

print can't do the format string thing. You'd need another buffer and use sprintf then print that buffer. We don't get printf with Arduino which is that you are trying to use here.

Yes.
I made a mistake in my previous post.

PaulS:

char pissAwayMemoryUselessly[80];

sprintf(pissAwayMemoryUselessly, "[%s] is a string %d chars long\n", buffer, n);
Serial.print(pissAwayMemoryUselessly);




There is NO benefit in doing this, though. NONE!
  1. It's supposed to be a demo, that's all. Just a demo.
  2. Once you declare the char arrays you intend to use as buffers, you can use them over and over again in your program.
  3. PaulS, you probably ought to see a therapist or something about your Asperger syndrome.

Keep it civil, please.

I rather enjoy PaulS's responses. He's the chuck Norus of the forum.