Im sending string commands from vb.net via serial to my arduino, which works well
serial.WriteLine("setnozzels:0x0FFF") or serial.WriteLine("setnozzels:0b0000110000001100")
Now my arduino recieves a string/ char array containing the command and the value. From here i extract both and try to handle it.
But i cant convert the value (string) to a word typ.
if (sline.indexOf("setnozzels") >=0) { // find string
String setnozzels = sline.substring(11,23);
Serial.println(setnozzels);
// here i need some stuff to convert the setnozzels string to word for the spray_ink function
// like: word activenozzels = word(setnozzels);
}
The reason for this is that i need to call a third person function which needs a word
But i cant convert the value (string) to a word typ.
You don't have a string. You have a String. They are NOT the same thing.
The Arduino is NOT running an operating system from those oddballs in Redmond, who felt it necessary to some up with new names for types that already had perfectly good names. Words have no place on the Arduino. Use a standard type.
Maybe u have an idea.
Well, if it were me, and I was forced to use a crappy class to create a crappy type, I'd probably use the piss-poorly named toInt() method, which does not return an int.
But, I don't know that the toInt() method handles binary or hex bases. Since you control the sending end, it boggles the mind why you don't send the data in base 10.
if (sline.indexOf("setnozzels") >=0) { // find string
String setnozzels = sline.substring(11,23);
//Serial.println(setnozzels);
unsigned int test = setnozzels.toInt();
Serial.println(test);
}
what i need to send is a 12 diggit binary code like "101010101010" or "111111111111" so "setnozzels:110000001100" is also ok, i dont need to send it in hex or binary base. but im still not able to convert in in a valid value for
Why? Why do you need to send a string representation of the value in base 2? Or in base 16? Send the string representation of the value in base 10!
nope, thats not what i meant
well, working examples for the called functions are
MyInkShield.spray_ink(0x0FFF);
or
MyInkShield.spray_ink(0b0000101010101010);
//spray all 12 nozzles as fast as possible
//(blackout pattern 0x0FFF = 0000111111111111)
MyInkShield.spray_ink(0x0FFF);
//or other patterns
//(every other nozzle 0x0AAA = 0000101010101010)
//MyInkShield.spray_ink(0x0AAA);
//(every other nozzle 0x0555 = 0000010101010101)
//MyInkShield.spray_ink(0x0555);
well, working examples for the called functions are
The compiler converts 0x0FFF or 0b0000101010101010 to some internal representation. It does not matter to the compiler whether you express the value in base 16, base 2, or base 10.
But, since YOU are not able to convert a String that contains a representation of a number in base 16 to a useful value, and YOU are not able to convert a String that contains a representation of a number in base 2 to a useful value, then it seems to me that you should NOT be sending representations of a number in any base you can not deal with. The toInt() method does know how to deal with a representation of a number in base 10.
So, it doesn't take a rocket scientist to decide that sending the value as a representation in base 10 is the ONLY way to go.
Building on pepe post, it might be easier to read this:
long val;
char test;
if ( strcmp("setnozzels:", sline) == 0) { // We have a match
if (sline[11]=='0') { // The char is a 0 digit character
if (sline[12] >= 'a') // Is it lower case?
test = sline[12] - 32; // Convert to upper case
switch (test) {
case 'X': // Hex
val = strtol(&sline[13], NULL, 16);
break;
case 'B': // Binary
val = strtol(&sline[13], NULL, 2);
break;
case 'O': // Octal
val = strtol(&sline[12], NULL, 8);
break;
default: // Decimal
val = strtol(&sline[11], NULL, 10);
break;
}
}
What happens if the character in position 12 is upper case? What is in test if that is the case?
Opps. And there are still some other potential errors that could happen (e.g., what it the string is only 11 characters long). Correcting those is left "as an exercise for the reader". I think my real reason for the post is to show that it is easier to read a switch than a cascading if block when possible.
if (sline[12] >= 'a') // Is it lower case?
test = sline[12] - 32; // Convert to upper case
else
test = sline[12];
Is switch/case/break "more readable" than few if/else enough to be worth increasing the length of the code ? I don't think so
True, it's a matter of choice. Your code is shorter (1380 bytes) than mine (1396), but I always find a switch easier to read. I wouldn't expect everyone to agree.
[quote author=_pepe_ link=topic=267547.msg1886639#msg1886639 date=1411040648]
Hi
Do you really need to use a String object ?
The standard C libraries provide the required functions to do what you want, but just with simple C strings (i.e. nul terminated character arrays).
}
na, i already get rid of the String object. Now i handle a incoming char[] object and sperate it by delimiter ":" into 2 char objects.
...
char line[LINE_BUFFER_SIZE];
...
if (strstr(line,":") != NULL) { //input line = "setnozzels:0x0FFF" i decided to send hex cause its the shortest
char *command = subStr(line, ":", 1); //subStr returns char*
char *value = subStr(line, ":", 2);
if (strcmp(command, "setnozzles") ==0 ){
Serial.println(value); //returns 0x0FFF
// im still to stupid to do the conversion here ;)
//word test = value //ofc dont work, but thats all what i want...
//unsigned long test = strtoul(value, NULL, 16);
//Serial.println(test); // return 4095 but i just want to have 0x0FFF
}
//and then finally call
inkshield.spray_ink(test)
//void InkShieldA0A3::spray_ink(word strip) {...}
Is switch/case/break "more readable" than few if/else enough to be worth increasing the length of the code ? I don't think so
True, it's a matter of choice. Your code is shorter (1380 bytes) than mine (1396), but I always find a switch easier to read. I wouldn't expect everyone to agree.
I'm with you on this. Suppose you have several (hundred?) __case__s. I'd get lost after the first 10 if/else/if statements.
...but there aren't lots of if/else statements here. In fact, testing sline[12] requires only two of them.
If I'm sure the switch/case block will never expand and there are only two if blocks, I'd probably write the block the way you prefer. If I see that I'm nudging memory limits and I'm using a switch/case, I'd also see if the cascading if block saves the day. That said, after teaching university-level programming courses for almost three decades, I can tell you that a switch/case block results in fewer bugs and, if there is a bug, switch/case is easier to read, making it is easier to isolate and correct than if the bug is in a cascading if block. Given that 80% of software development costs are absorbed in testing and debugging, and assuming that switch/case blocks are a viable alternative, I always prefer switch/case.
I don't particularly prefer if/else or switch/case structures. Anyway, they are not strictly equivalent. But I use either, according to the needs and the constraints of the project (speed/size optimizations, potential evolutions of the code, etc.).
The right tool for the job is almost always the best approach.
Of course, knowing which tool is the right tool comes only with experience.