The loyal reader of this blog knows I have written a blog entry with a similar title before. However as I keep on using this set of libraries I also keep on improving the libraries. Therefore the old article is getting outdated on the level of practical implementation. I also recently updated all the examples using my new arduino eclipse example link feature so I guess it is time for a rewrite/reread.
Why read this article
What would you think about controlling an Arduino over the network in a easy and generic way?
In a way you only need to change the code and all processes after that are generically enough to change without having to change code?
In a way you can intervene in the intermediate steps?
In a way you automagically get a web interface that allows you to read Arduino variables, set them and save them in eeprom, in a way you fully control/understand?
Does that sound appealing?
Well than you should sit and read this and the next planned blog posts.
These posts will lead you to an example that reads out the position of 3 potmeters connected to A0,A1 and A3. Below is a browser dump of the HTML control.
It's a long road, and we'll start slow, but if you need this functionality you'd better hold on tight. On the road you'll also learn how to save setting in eeprom/yun sd card simply by setting a flag in your code.
Lets get started:
As you probably know the easiest way to communicate with an arduino is the serial port. However the serial port is a byte by byte protocol and as such needs another layer to communicate at a higher level.
People tend to work on a line by line basis. An experienced programmer can easily put a layer on the serial port to do line by line reading. As such it seems kind of crazy to make a line by line reading library. However for building on top of a line by line reader a library is needed. As it is a functionality which is requested by Arduino enthusiasts it deserves it's own library -in Arduino land-.
So lets start with the first example: a simple line by line reader to get used to the jantje's way.
//for the stream you want to read info from you need to declare a SerialStringReader
//you can only have one
//Define that the USB serial (pin 0 and 1 on the uno) is to be used by the mySerialReader
//If you want to use the yun with the bridge use Serial1
#define THESERIAL Serial
Stream &SerialInput = THESERIAL;
Stream &SerialOutput = THESERIAL;
//always add the following line to your loop
//mySerialReader.messageReceived() will only return true when a line of data has arrived
SerialOutput.println("You have send a message to Arduino.");
SerialOutput.println("And the message is:");
// with mySerialReader.getMessage() we get the actual message
// for the demo we simply play it back.
How to use the sketch
Download the library SerialStringReader from github https://github.com/jantje/libraries
Open the example serialCommunicatorStep1
Verify and Upload the sketch. Open the serial monitor (115200 baud) and send messages to Arduino.
Only when an end of line is send Arduino will send the info back.
That is all it does and it does it good :-D
Looking at the sketch code
The first thing I ask you to do when looking at the code is to forget the THESERIAL and SerialOutput for now. See them as simply Serial.
Working with Arduino and classes I got used to adding a setup() and loop() to all my classes. This makes that I can simply extend my existing sketches with functionality by creating a new class instance and simply call the setup and loop in setup and loop. -It probably makes more sense to read the code than reading the previous text ;-) -
This way of working will come back in all the examples here.
First I create an object called myCommunicator of type SerialStringReader.
I call the myCommunicator.setup in setup and myCommunicator.loop in loop. If later on I change the type of myCommunicator to something else there is very little to change.
myCommunicator.messageReceived() tells when a message is received and myCommunicator.getMessage() returns you the message. This is line by line.
The end of line is identified by a CR or LF or both.
Looking at the library code
If you look at the code in the library you will find that setup is blank. Here setup() only exists for compatibility reasons.
And here is the code of loop
while ((!myHasMessage) && (SerialInput.available() > 0))
char aChar = SerialInput.read();
if ((aChar == '\n') || (aChar == '\r'))
myHasMessage = myMessageIndex; //this way if \n and \r are send we do not get 2 messages
myMessageIndex = 0;
myMessage[myMessageIndex] = aChar;
myMessage[++myMessageIndex] = 0; // Keep the string NULL terminated
if (myMessageIndex >= MAX_MESSAGE_LENGTH)
SerialOutput.print(F("Message to long. Max: "));
I use an array to avoid the payload of the string. The size of that array is
#define MAX_MESSAGE_LENGTH (uint8_t)80
80 may seem a bit tight but do not forget serial is a slow protocol. The longer your message the more time. Also the longer the message the more you lose program and data space. To save space I also use uint8_t so if you want messages longer that 255 you'll need to adopt the code.
Some framework explanation
Now what is this THESERIAL and serialOutput defines/variables about?
These defines and variables I use to easely swap between serial ports.
If you use the yun and want to communicate with the linux part of the yun you need Serial1. However if you connect a UNO to a PC running linux you want Serial. I have connected a MEGA to a yun and I use Serial2.
To be able to swap easily I use THESERIAl and serialInput serialOutput serialError. Like in Linux.
You can swap serial port by simply changing the #define THESERIAL to the wanted port/Stream.
This sample code is Arduino IDE programming level compatible. I do not advice to use the arduino eclipse plugin if you want to stay on this level.
What is next
In the next example we continue this slow pace and blink a LED. How Arduino that is :-)