Hi, I have problem with concatenating two long Strings. String "tmp" should contain "a9993e364706816aba3e25717850c26c9cd0d89d" for input "abc", but contains only "a9993e364706816aba3e2". When I try add "tmp" to "stringData" it doesn't work.
In RS-232 output:
a9993e364706816aba3e2
?btn1=OFF&btn2=ON&sha1=
My code:
void loop() {
int buttonState1 = digitalRead(inputButton1);
int buttonState2 = digitalRead(inputButton1);
String stringData = String(200);
stringData = "";
stringData.concat("?btn1=");
if (digitalRead(inputButton1) == HIGH)
stringData.concat("ON");
else
stringData.concat("OFF");
stringData.concat("&btn2=");
if (digitalRead(inputButton2) == HIGH)
stringData.concat("ON");
else
stringData.concat("OFF");
stringData.concat("&sha1=");
Sha1.init();
Sha1.print("abc");
uint8_t *hash = Sha1.result();
int i;
String tmp = String(100);
tmp="";
for (i=0; i<20; i++) {
tmp += "0123456789abcdef"[hash[i]>>4];
tmp += "0123456789abcdef"[hash[i]&0xf];
}
Serial.println(tmp);
stringData.concat(tmp);
char stringToSend[200];
stringData.toCharArray(stringToSend, 200);
Serial.println(stringToSend);
}
Please help me.
String tmp = String(100);
That does not create a 100 byte string, it creates a string containing "100".
Please note that in versions of the IDE up to and including 1.0.3, the String library has bugs as discussed here and here .
In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.
I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.
Alternatively, install the fix described here: Fixing String Crashes
Preferably upgrade your IDE to version 1.0.4 or above at: http://arduino.cc/en/Main/Software
system
September 1, 2013, 9:51am
3
Pretty much all your code can be replaced with a sprintf() call and one single char array instead of messing with the String object. I certainly wouldn't recommend using Strings (even with Nick's recommended fixes [btw, I bet you have that as a macro key now don't you Nick? ]) on a board that only has a few KiB of RAM. On the Due it's fine, but certainly not on anything smaller.
char stringToSend[70];
char tmp[41];
bzero(tmp, 41);
for (i=0; i<20; i++) {
tmp[i*2] = "0123456789abcdef"[hash[i]>>4];
tmp[i*2+1] = "0123456789abcdef"[hash[i]&0xf];
}
sprintf(stringToSend, "?btn1=%s&btn2=%s&sha1=%s",
digitalRead(inputButton1) ? "ON" : "OFF",
digitalRead(inputButton2) ? "ON" : "OFF",
tmp
);
Serial.println(stringToSend);
... or something similar.
majenko:
#include <strings.h>
...
char tmp[41];
bzero(tmp, 41);
int i=0;
for (i=0; i<20; i++) {
...
When I try your code I get this error:
Client.ino: In function ‘void loop()’:
Client:60: error: ‘bzero’ was not declared in this scope
In which library is function bzero() ? Where is an error?
Thank you.
I have Arduino 1.0.5 x86_64 on Linux.
zoomkat
September 1, 2013, 11:52am
6
If cryptic code like "btn1=%s&btn2=%s&sha1=%s"," are not your thing yet, the below String info might have easier to understand String examples to do what you want.
The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.
system
September 1, 2013, 12:07pm
7
martin159:
majenko:
#include <strings.h>
...
char tmp[41];
bzero(tmp, 41);
int i=0;
for (i=0; i<20; i++) {
...
When I try your code I get this error:
Client.ino: In function ‘void loop()’:
Client:60: error: ‘bzero’ was not declared in this scope
In which library is function *bzero()*? Where is an error?
Thank you.
I have Arduino 1.0.5 x86_64 on Linux.
Humph... Pesky Arduino missing standard library functions...
try memset(temp, 0, 41); instead.
majenko:
try memset(temp, 0, 41); instead.
Thank you, memset works fine.
I need put buttons status to string, create hash of this string and put hash to end of string (hash(btn1=OFF&btn2=ON&sha1=)) . Now I have this working code:
void loop() {
delay(1000);
int buttonState1 = digitalRead(inputButton1);
int buttonState2 = digitalRead(inputButton1);
char stringToSend[70];
char tmp[41];
memset(tmp, 0, 41);
sprintf(stringToSend, "?btn1=%s&btn2=%s&sha1=",
digitalRead(inputButton1) ? "ON" : "OFF",
digitalRead(inputButton2) ? "ON" : "OFF"
);
Sha1.init();
Sha1.print(stringToSend);
uint8_t *hash = Sha1.result();
for (int i=0; i<20; i++) {
tmp[i*2] = "0123456789abcdef"[hash[i]>>4];
tmp[i*2+1] = "0123456789abcdef"[hash[i]&0xf];
}
sprintf(stringToSend, "%s%s", stringToSend, tmp );
Serial.println(stringToSend);
}
Output is ok:
?btn1=OFF&btn2=ON&sha1=65737ac78f075de8e67a5baa0cfd9eacbedc3e1a
Is it good, or I have inefficient and complicated code?
system
September 1, 2013, 1:28pm
9
Instead of the second sprintf you could use strcat:
strcat(stringToSend, tmp);