Blogue de Guillaume DALLAIRE's Blog

October 29, 2008

RS485 Arduino Network

Filed under: Uncategorized — Tags: , , , — gdallaire @ 10:52 pm

Recently I started wondering about the fact that most of my MCU based projects use a RS232 serial port to exchange data between my “base” computer and every modules. Since the number of serial ports is limited (normally 2) on a normal PC, this is a problem.

After some reading, I decided to try a RS485 bus: A multipoint serial communication channel that would be both simple and cheap to implement inside my projects. The first thing to do is to test this technology by prototyping a half-duplex RS485 bus with some Arduino MCU.

75176 RS485 Transceiver pinout

75176 RS485 Transceiver pinout

Let’s find a transceiver. Two chips seem to be commonly used : The MAX485 (or DS485, the Nationnal Semiconductor equivalent) and the SN75176BP. See this Maxim comparision page. I choose the SN75176BP, only 0.71$CAD.

Connection between the Arduino and the 75176

Connection between the Arduino and the 75176

Each MCU has its own 75176 connected to the UART (RO and DI). The RE and DE pins are connected together to a digital output allowing the MCU to control the “direction” of the data flow with the bus. When this line is LOW, the transceiver is in “receiving” mode. At a HIGH level, the transceiver switch to the “sending” mode.

Note that the RE/DE pins can be connected to any MCU’s digital output.

The RS485’s topology is multipoint. This means that every node in the network shares the same media, then without collision avoidance mechanism (which is relatively complex to implement), only one node can be defined as a master. The master sends commands or data and zero or more slaves respond to the master (It’s an important limitation).

I built my prototype around 1 master and 3 slaves:

My bench

My bench

The blue and white wires are the RS485 physical bus. Slave #1 has 2 sensors (barometric and RH), slave #2 and #3 are simple LED display. The master reads the sensors by sending slave’s #1 address, this slave sends the values (current RH+pressure), the master reads it and finally, it sets the displays by calling each slave’s (#2 and #3) address with the data to show. The RS485 transmit function looks like this:

void rs485TxMsg(char *msg)
{
  Serial.flush();
  digitalWrite(txPin, HIGH);
  delay(10);
  Serial.println(msg);
  delay(10);
  digitalWrite(txPin, LOW);
}

The read function :

void rs485RxMsg(char *msg, byte msgLen)
{
  byte i = 0;
  char val;
  msg[0] = 0;
  while(Serial.available())
  {
    val = Serial.read();
    if (val == '\r')
      msg[i++] = 0;
    if (val == '\n')
    {
      msg[i++] = 0;
      return;
    }
    msg[i++] = val;
    if (i>msgLen)
      return;
  }
}

The “message” separator are the “\r\n” characters. A more elaborate format would be needed in production and CRC checking (or equivalent) would be also a good thing.

For now I succesfully got a working system very easily. RS485 is simple and cheap to implement for a MCU based system.

October 26, 2008

Python

Filed under: python — Tags: , , — gdallaire @ 1:36 pm

The Python language is present in my life since about 1 year now. It’s hard to express how good it has been for me but this cartoon is a good example of “a picture is worth a thousand words”.  Here are some other good ones about Python too:

October 25, 2008

Humidity Sensor controlled Bathroom Fan

Filed under: electronic — Tags: , — gdallaire @ 10:07 pm

A bathroom fan should always be switched ON when a predetermined level of humidity is reached, always.

Some months ago, I built a controller to fulfill this requirement using a microcontroller, a humidity sensor and a solid state relay. In these lines, I will expose my selection process for the sensor.

HS1101 Humidity Sensor

HS1101 Humidity Sensor

There are a lot available, but rarely above 10$. I decided to try a capacitive humidity sensor: HS1101 from Humirel. This is the cheapest I found (from Digikey), but it requires a special circuit to convert the capacitive output to something a MCU can read.

I followed the recommendations found in the HS1101’s datasheet, a frequency output circuit:

Frequency output circuit for HS1101

It’s a simple 555 timer that transform the sensor’s output to a frequency that any normal MCU can use. I connected this frequency output to the MCU’s external timer input and programmed the reversed polynomial function.

The result was good but not perfect since I used normal precision discrete components around the 555. The biggest problem was a really not linear response over different temperatures. So my fan wouldn’t turning ON during summer with the winter’s calibration… Bad..

HIH-4030-003S2 Humidity Sensor

HIH-4030-003S2 Humidity Sensor

At this point, I had two choices: To order the right discrete components or to try another kind of sensor. I decided to try a sensor that outputs a linear voltage vs %RH. I choose the HIH-4030-003S :

Connected directly to an MCU’s analog input, the RH value is calculated using the factory data provided with each sensor:

Vout=Vsupply(0.176 to 0.759)

RH=(Vout-0.819)/31.488

If we have Vsupply = 5 and the analog value readout (val) from 0 to 1023, then Vout = (val*5)/1024. RH is then calculated with (Arduino Code here) :

val = analogRead(rhPin);
rh = (((val * 5) / 1024) - 0.84 ) / 31.488;

With this sensor, the system is stable at different temperatures.

I plan to use this kind of sensor for my home meteorological station. For now, my conclusion is simple: Use smarter sensor and save time !

Powered by WordPress