Please note the commas between each numerical entry. You should now see a pattern like this:
You will notice that the commas have been replaced by line feeds, and each number should display on a new line.
In this stage, we are going to get the Arduino to do simple maths. We will send it two integers (or whole numbers), and the Arduino will do the hard work and send us the answer in no time at all.
This might seem like a simple task, but when you send a number like 27 to the Arduino, it does not receive the number 27. It receives 2 and then 7 in byte form. In other words, the Arduino will see the byte codes 50 and then 55 as per the
ASCII table on this page.
One way to convert this byte code back to a 2 and a 7 is to subtract 48 from each byte received, providing the byte is in the range 48 to 57 inclusive (which equates to the numbers 0-9).
We are not done yet. We then need to join these numbers to make 27.
Step1: Subtract 48 from the bytes received, only if the bytes are in the range 48 to 57.
Example: 50 - 48 = 2
55- 48 = 7
Step2: Multiply the previous number by 10, before adding the most recent byte received.
Example: (2 x 10) + 7 = 27
If we have a number like 1928, then we would create this number using the following calculation
1 = 1
(1 x 10) + 9 = 10 + 9 = 19
(19 x 10) + 2 = 190 + 2 = 192
(192 x 10) + 8 = 1920 + 8 = 1928
Step3: Use a "+" sign as a delimiter so that the Arduino can move onto the Second number
Step4: Capture the second number as per Step2. An "=" sign will tell the Arduino that it has reached the end of the second number, and to proceed to step 5.
Step5: Add the 2 numbers together and send back the answer.
The following code will carry out the 5 steps above.
Enter the following sketch into your Arduino IDE and upload it to your Arduino.
Arduino Sketch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /* Simple Serial ECHO script : Written by ScottC 05/07/2012 */ /* Stage 3: Arduino Maths: Simple Addition */
/* Global variables needed for programming workflow byteRead: holds the value being read from the COM port num1: holds the entire first number num2: holds the entire second number answer: holds the sum of num1 and num2 mySwitch: enables the switch between num1 and num2 */ byte byteRead; long num1, num2,answer; boolean mySwitch=false;
void setup() { /* Turn the Serial Protocol ON and initialise num1 and num2 variables.*/ Serial.begin(9600); num1=0; num2=0; }
void loop() { /* check if data has been sent from the computer: */ while (Serial.available()) { /* read the most recent byte */ byteRead = Serial.read(); //listen for numbers between 0-9 if(byteRead>47 && byteRead<58){ //number found /* If mySwitch is true, then populate the num1 variable otherwise populate the num2 variable*/ if(!mySwitch){ num1=(num1*10)+(byteRead-48); }else{ num2=(num2*10)+(byteRead-48); } } /*Listen for an equal sign (byte code 61) to calculate the answer and send it back to the serial monitor screen*/ if(byteRead==61){ answer=num1+num2; Serial.print(num1); Serial.print("+"); Serial.print(num2); Serial.print("="); Serial.println(answer); /* Reset the variables for the next round */ num1=0; num2=0; mySwitch=false; /* Listen for the addition sign (byte code 43). This is used as a delimiter to help define num1 from num2 */ }else if (byteRead==43){ mySwitch=true; } } }
|
The above code was formatted using this site Instructions
1. Once the code has been uploaded to the Arduino, open the Serial Monitor once again and type the following sequence:
1+2= <enter>You should get the following message sent back to Serial Monitor
1+2=3 Things to Try
1. Enter this sequence:
10 <enter> + <enter> 10 <enter> = <enter> Result:
10+10=20--------------------------------------------------------------------2. Enter this sequence:
10 <enter> 20 <enter> +5= <enter> Result:
1020+5=1025--------------------------------------------------------------------3. Enter this sequence:
10+20+30= <enter> Result:
10+2030=2040I have specifically written this script to add
two whole numbers together. If you start to introduce more complicated calculations, the results become unpredictable.
--------------------------------------------------------------------4. Enter this sequence:
1.2+1.0= <enter> Result:
12+10=22Once again, I have only designed this script to handle whole numbers. Therefore, decimal points are ignored.
--------------------------------------------------------------------5. Enter this sequence:
-5 + 10= <enter> Result:
5+10=15This script ignores the negative sign, and treats the -5 as a positive 5.
I have done this on purpose. I wanted to show you how the Arduino reads numbers from the com port, and how easy it is to exclude vital functionality in your code. I have kept this script simple, however, if you wanted to, you could make the Arduino deal with each of the above situations and more. Multiplication, division and subtraction is handled in the same way.
This is the last thing I want you to try before we go to the next stage:
6. Enter this sequence:
2147483646+1= <enter> Result:
2147483646+1=2147483647 2147483647+1= <enter> Result:
2147483647+1=-2147483648Note that the maximum size of a "long" number is 2147483647. If you add one to this number, the result is equal to the minimum size of a "long" which is -2147483648.
STAGE 4: Sending doubles to Arduino : The double doubler
Now we get to some tricky business. Sending and receiving Doubles (to and from) the Arduino.
Up until now, I have tried to keep it simple using whole numbers, but there will come a time when you will want to send a fraction of a number through the Serial line.
To test our program, we will want to send a very small number to the Arduino, multiply the number by 2, and return it back.
Our final test is to try a number like : 0.000001
and then a number like: 123.321
IMPORTANT NOTE: When the Arduino sends a float or a double through the COM port using Serial.print() or Serial.println(), it will automatically send the number to 2 decimal places.
A number like 1.2345 will appear as 1.23, and a number like 1.9996 will appear as 2.00
To demonstrate this, we will get the Arduino to send these floats/doubles to the Serial Monitor.
Enter the following sketch into your Arduino IDE and upload it to your Arduino.
Arduino Sketch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* Stage 4: Simple Transmission of a Double Written by ScottC on 7/7/2012 */
/* Declare the doubles that will be sent to the Serial Monitor */ double myDub1, myDub2;
/* This part of the program only runs ONCE */
void setup(){
/* Turn ON Serial Communication */ Serial.begin(9600); /* Assign a value 1.2345 and 1.9996 to the Doubles being sent */ myDub1=1.2345; myDub2=1.9996; /*Send the values to the Serial Monitor */ Serial.print("myDub1 (1.2345) : "); Serial.println(myDub1); Serial.print("myDub2 (1.9996) : "); Serial.println(myDub2); }
void loop(){ //Loop does nothing }
|
The above code was formatted using this siteWhen you open the Serial monitor (after you have uploaded the sketch above), you will notice the following output:
myDub1 (1.2345) : 1.23 myDub2 (1.9996) : 2.00
The
blue text represents the string (or array of characters) being sent using lines 19 and 21.
The
red text represents the actual double being sent using lines 20 and 22.
You will notice that myDub2 rounds to 2.00. This may or may not be what you want.
If you wish to increase the number of decimal places, then you will need to change lines 20 and 22 to the following:
20 Serial.println(myDub1,4);22 Serial.println(myDub2,4);The number 4 highlighted in red, indicates the number of decimal places you wish to send.
Try it ! And try changing this number to something bigger or smaller.
---------------------------------------------------------------------------------------------------
Ok - now that we understand this little Serial.print(double,decimals) trick, we will now get the Arduino to echo back a Double.
Before we jump in, perhaps we should try and map out our strategy. For this we will choose a simple decimal to make it easier. So in this example, we will choose
0.1 Once we get this working, we can then do our final test (as mentioned above).
If we send 0.1 to the Arduino, it will read the following byte code
48 0
46 .
49 1
We can use the decimal point as a delimiter.
We will use the following 5 steps to echo the double back to the Serial Monitor:
Step1: Arduino collects all numbers before the decimal point using the same technique as in Stage3.
Step2: When the Arduino receives byte code 46, it will go into decimal mode.
Step3: The Arduino will collect numbers after the decimal point using a similar technique to step1.
Step4: Use maths to create the double, and then multiply it by 2
Step5: Display the doubled Double value in the Serial monitor.
Enter the following sketch into your Arduino IDE and upload it to your Arduino.
Arduino Sketch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | /* Simple Serial ECHO script : Written by ScottC 06/07/2012 */ /* Stage 4: Double doubler */
/* Global variables needed for programming workflow ------------------------------------------------------ byteRead: holds the value being read from the COM port num1: holds the number before the decimal point num2: holds the number after the decimal point complNum: holds the complete number (before multiplation) answer: holds the final value after multiplication counter: is used to convert num2 to the number after the decimal numOfDec: counts the numbers after the decimal point mySwitch: enables the switch between num1 and num2 */ byte byteRead; double num1, num2; double complNum,answer,counter; int numOfDec; boolean mySwitch=false;
void setup() { /* Turn the Serial Protocol ON and initialise num1 and num2 variables.*/ Serial.begin(9600); num1=0; num2=0; complNum=0; counter=1; numOfDec=0; }
void loop() { /* check if data has been sent from the computer: */ while (Serial.available()) { /* read the most recent byte */ byteRead = Serial.read(); //listen for numbers between 0-9 if(byteRead>47 && byteRead<58){ //number found /* If mySwitch is true, then populate the num1 variable otherwise populate the num2 variable*/ if(!mySwitch){ num1=(num1*10)+(byteRead-48); }else{ num2=(num2*10)+(byteRead-48); /* These counters are important */ counter=counter*10; numOfDec++; } } /*Listen for an equal sign (byte code 61) to calculate the answer and send it back to the serial monitor screen*/ if(byteRead==61){ /* Create the double from num1 and num2 */ complNum=num1+(num2/(counter)); /* Multiply the double by 2 */ answer=complNum*2; /* Send the result to the Serial Monitor */ Serial.print(complNum,numOfDec); Serial.print(" x 2 = "); Serial.println(answer,numOfDec); /* Reset the variables for the next round */ num1=0; num2=0; complNum=0; counter=1; mySwitch=false; numOfDec=0; /* Listen for the decimal point (byte code 46). This is used as a delimiter to help define num1 from num2 */ }else if (byteRead==46){ mySwitch=true; } } }
|
Things to Try
1. Type the following into the serial monitor:
1.2= <enter> Result: 1.2 x 2 = 2.4
Make sure that you type the equal sign (=) before you press enter, otherwise the Arduino will not know that you are finished, and will not send anything back.
--------------------------------------------------------------------
2. Type the following into the serial monitor:
100.001= <enter> Result: 100.001 x 2 = 200.002
You will notice that the Arduino is formatting the decimal to the SAME number of decimals as that entered.
This is controlled by the variable: numOfDec.
---------------------------------------------------------------------
3. Now for our final test: Type the following into the serial monitor:
0.000001= <enter> Result: 0.000001 x 2 = 0.000002
First test: PASSED
----------------------------------------------------------------------
4. Type the following into the Serial monitor for our last test:
123.321= <enter> Result: 123.321 x 2 = 246.642
Second test: PASSED
-----------------------------------------------------------------------
BEWARE: While everything looks perfect, let me tell you that it isn't. But hopefully this code will help you get on the right track. If you decide to type in a number like 123123.111222, you will not get the answer you expected.
I have found that this program will work if the amount of numbers before and after the decimal point are less than about 9. Eg. 1234.1234 will produce the right result.
However, 11111.2222 will NOT, because there are 9 numbers represented.
I think this has something to do with the memory allocated to a double, but I am not sure.
I don't know if people work with these types of numbers, but I am sure there is a workaround, and I am sure someone out there can work it out. I don't personally need this kind of precision, but thought to mention it just in case you do.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
STAGE 5: Sending sensor data to the Serial Monitor
We know the Arduino is very good at copy-Cat games, how about getting the Arduino to send us some data from one of our sensors. We will use the Serial Monitor to view the sensor data.
Disconnect the USB cable, and hook up one of your favourite analog sensors to your Arduino. For simplicity, I am going to hook up a potentiometer as per the Fritzing sketch below.
Parts Required
- Arduino UNO (or equivalent)
- Computer with USB cable
- Breadboard
- Potentiometer
- 3 Wires
Arduino Fritzing Sketch
Once you have attached your sensor to the board, plug your USB cable into the Arduino, and upload the following sketch.
Arduino Sketch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* Stage 5: Send Sensor Value to Serial Monitor Written by ScottC on 7/7/2012 */
int sensorVal = 0;
void setup() { // Setup Serial communication with computer Serial.begin(9600); }
void loop() { // Read the value from the sensor: sensorVal = analogRead(A0); // Send the value to the Serial Monitor Serial.print("Sensor Value="); Serial.println(sensorVal);
// Interval between readings = 1 second delay(1000); }
|
The above code was formatted using this site
Instructions