Hello!
In the previous post, I had figured out how to control the robot by sending commands through MATLAB.
The next step? Controlling the robot with a simulated neural network: I looked for MATLAB scripts with only a few neurons, and actually found a really nice one. Bonus: it’s customizable :).
I fiddled around with some code using the above function for a while based on the examples provided, and settled on this:
W = log(abs(randn(4))); [spk NetParams V] = SimLIFNet(W,'simTime',35,'tstep',1e-2,... 'offsetCurrents',1.1*ones(length(W),1)); v = round(V, 3);
Where the Title Comes In
I was trying to implement this, but then ran into the issue of sending larger numbers, or packets, to Arduino. I knew it was possible via XBee, but I wasn’t sure how to do it.
My initial idea was the set ‘start’ and ‘stop’ characters that I could use to surround digits to identify them as a single number. A very-long-story-short, it took me more than a couple hours to figure out, but this is what I came up with:
//"sketch_jan16a" void setup() { // initialize serial ports Serial.begin(9600); // USB serial port 0 Serial.println("Starting up..."); Serial3.begin(9600); // serial port 3 } byte rx_byte = 0; // stores received byte String str; void loop() { if (Serial.available()) { rx_byte = Serial.read(); Serial3.write(rx_byte); } if (Serial3.available()) { rx_byte = Serial3.read(); if(rx_byte == '{') { Serial.println("start"); str = ""; } else if(rx_byte == '}') { Serial.println(); Serial.println("end"); Serial.println("final string: " + str); function(str); } else{ Serial.write(rx_byte); char c = rx_byte; str = str + c; } } } void function(String str) { double num = str.toFloat(); Serial.print("String to Double: "); Serial.println(num); }
A Video of It Working:
Here’s a Quick Rundown of How it Works:
- I initialize the Serial ports: plain ‘Serial’ refers to the Arduino’s Serial Monitor, and ‘Serial3’ refers to the hardware serial pins that I’ve connected the robot-XBee to on the MEGA.
- I initialize a string
- After checking that both ‘serial’s are available, the program reads in the character sent to the robot-XBee as a byte
- The program throw away all the bytes until I receive one representing ‘{‘; when it receives that, the Arduino’s Serial Monitor prints out “start” to let me know
- Here’s the important part (that took me lots of trial and error to find):
- The program clears the previously initialized string (this is to account for the ‘looping’ of ‘void loop’)
- Order is important here: it reads in the next byte, first checking that it is not ‘}’, and then adds it to the string
- It continues to add characters to the previously initialized string until it receives the ‘end’ character, ‘}’
- It then prints out the final character on the Serial Monitor
- You’ll note I then have it call a function, aptly named ‘function’ (lol):
- This function converts the string to a Float (ie. a type of number). I had wanted to convert to a double… but more on that later
- Then I basically have it print out the number as a number for good measure.
What I intend to have ‘function()’ do is multiply that number, ‘num’, by 250 and then call the ‘setSpeeds()’ function, etc, (detailed in previous posts)–> ta-da, we are controlling the wheels!
But: Also to Do Before I Test It on the Ground
Sending Packets with XBee & XTCU
Long story short, see here and here. 🙂
Other Useful Links:
I really found an ASCII table useful, even though you can use ‘Serial.print(rx_byte)’ to see the the DEC value of the character you send, and XTCU displays the HEX one right on-screen.
And I think I may have found this Arduino forum semi-helpful…?
Floats
I’ve always been sort of wary of floats, because I’ve heard they’re unnecessarily complicated to use: I’m an ‘int‘ type of person, lol.
In this particular instance, however, I couldn’t use ints because I was working with decimal numbers (which, for reference, is one of the reasons I stored the bytes as a string before converting to a type-of number). I had wanted to use a Double, and so I was pleased to find that Arduino’s String class has a command called ‘toDouble()‘.
It does not work. These people will corroborate.
What does work is ‘toFloat()’, and floats can support decimal numbers, so that’s what I’m using now. I got more wary, however, when I read in the float online API/reference that it sometimes didn’t do math (specifically: multiplication/division) correctly.
“Floating point numbers are not exact, and may yield strange results when compared. For example 6.0 / 3.0 may not equal 2.0. You should instead check that the absolute value of the difference between the numbers is less than some small number.” –the API/reference
void setup() { // put your setup code here, to run once: float a = 6.0; float b = 3.0; float c = a/b; Serial.begin(9600); Serial.println(c); } void loop() { // put your main code here, to run repeatedly: }