Arduino + Raspberry Pi – Learning about Serial Communications

 

When I created the first version of the webpage displaying the temperature and humidity readings recorded by the DHT11 temperature & humidity sensor, connected to the Arduino Uno which in turn was connected over USB to my Raspberry Pi, I was both satisfied that I had got it to work, but also not satisfied, because it didn’t feel ready yet.

There were a number of things that I wasn’t content about:

  • All code was in written in Python. I know that is thé language to use if you want to be considered a good Raspberry Pi hacker, but I prefer PHP.  I wanted to be able to get it to work without pySerial and Flask.
  • The current process didn’t feel efficient: the RPi was just pushing data unto the serial line 24/7. Even if I would not request the page for a day or a week, it would keep on sending data. That did not sound like the best way to do things. I wanted it to only send data whenever needed.

PHP Serial

I started by looking for an alternative to Python. I ended up using the php-serial class. No need to install anything at Linux level, just a PHP file that I would need to include whenever I needed to use the serial port. And since I was using Linux the class allowed for both reading from the serial port and writing to it. So I would be able to receive data from the Arduino and send data (commands) to it. Perfect.

Arduino Auto Reset on Open

OK, not completely perfect. But that had nothing to do with PHP. At first I ended up with a lot of inconsistent data. It turns out that the Arduino has a unexpected default behavior. Whenever you open the serial connection, it resets itself first. That means that if you want to connect to it using Python or PHP, you have to account for a bit of extra time so that the Arduino can reset. Fine, no problem, just stick a sleep() command in the code and we’re done. Not quite. Because as soon as a second client connect (say, if someone else tries to access the web page with the gauges), another serial connection is opened. And the Arduino resets again. Even if it was in the middle of transmitting data to one or more other clients that are connected.

It took a long time before I realized that this was happening. It was due to the LCD display that I had connected to the setup, that I noticed that it was resetting over and over again.
16x2 LCD

Luckily there is a fix for this problem. This page describes the options. I went for the option of putting a 100μF capacitator (10μF should be enough,  but I didn’t have one of those around) between the Ground and the Reset ports of the Arduino Uno.

I now just have to remember that whenever I want to upload a new sketch to the Arduino, I have to briefly disconnect the cable that is attached to the Reset port for it to work.

Turning the world upside down

Now, the second problem of the Arduino just keeping on sending data, also took a bit longer that it should have to fix. At first, I created a SwitchCase loop on the Arduino side that would simply listen for commands over the serial port while in the mean time continuing to update the LCD display with temperature and humidity data.

I would send a “start sending” command code from the Raspberry Pi to the Arduino when the page was loaded, wait for the data to arrive and then send a “stop sending” command. The PHP page would, just like the Python version had done, then auto-update every second by repeating this process.

Even writing it down now, kind of makes it sound like it could work. But I had not realized that the Arduino treats the serial bus as a single bus. So if a second page is opened, and a second instance of the PHP script wants to retrieve the data, something like this could happen:

PHP1: “start sending”
Arduino: {23.00,40.00}
Arduino: {23.00,40.00}
PHP2: “start sending”
PHP1: “stop sending”

In this case the PHP1 instance would send the start sending command, wait for the Arduino to send data and after having received that data sent the stop sending command. However, it might just as well be that in the meantime another script had also send the start sending command. Even so, the Arduino would stop sending data to the serial bus after the first script has finished, leaving the second script without any data.

One option that I considered was to have the Arduino track how many instances were connected so that it would only stop sending data if nobody was connected. But that would be very complex and error prone. So I decided to do it like this: if the Arduino receives a “start sending” command, it starts outputting the data for 3 seconds. After that it stops sending. However, every time a new “start sending” command is received, the 3 second timer is reset. No “stop sending” command is sent by the PHP instances. So in the above example, the arrival of PHP2 would just reset the timer and the Arduino would continue to transmit the data for another 3 seconds. If after that no new instance would connect, it would stop sending. This allows for multiple instances of the page to be opened while the Arduino only sends one set of data over the line, for as long as is needed.

The code

You can download the PHP-files here.

You can download the Arduino sketch here.

Note that I also included some extra functionality. If you call the page using:

?d=1 it turns on debugging, meaning that the LCD display will show debug messages.
?d=0 turns it off again.
?lcd=0 turns off the LCD display (though not the backlight)
?lcd=1 turns it on again
?m=test makes the LCD display show “test” or any other text (up to 100 characters)

Credits for the php-serial code go to Rémy Sanchez and a number of others that helped him (see the PHP file for a more complete list).
Credits for the jgauge code go to Dariab Cabod.

Mijn eerste breadboard als schema
The drawing of my current wiring of the breadboard created using Fritzing.
p.s. I am planning to re-do the wiring for the LCD display so that I can control the back-light using code. I want to be able to switch it on/off completely.

Deel dit bericht:

  Een reactie aan “Arduino + Raspberry Pi – Learning about Serial Communications”

Reacties (1)
  1. Bedankt voor de tip over de condensator. Nu schakelen m’n stopcontacten wél realtime, zonder 2 seconden vertraging.