Thursday 24 January 2013

A basic temperature web server

With the help of jQuery Mobile , 1-Wire libraries and yet, another Ethernet library - EtherCard, a proper page is up and running.


Only 2 sensors at the moment, one inside and one outside as you can imagine.
Although the 1-Wire bus and the software can have many more, the other sensors I have across the house are too far from the router and I need to get a wire across.
The 1-Wire hardware is very simple: the bus is connected to an I/O pin with a pull-up resistor to VCC, the strong pull-up to allow temperature conversion with parasite power is achieved by setting the pin to output high by software to get more current into the bus.
The code use the DallasTemperature library by Miles Burton, which use the OneWire library to manage the bus itself.

The main challenge is to fit the code and the web content (html, css, js) on the small program memory the processor have (30KB), and to make sure each response does not exceed the TCP/IP buffer size I have allocated (1KB).
jQuery CDN to my rescue!
This has 2 advantages: a) I don't need to store the jQuery on the processor. b) the files are probably already got into my device cache when I browsed other mobile sites.

The HTML:

<!DOCTYPE html>
<html>
<head>
  <meta name='viewport' content='width=device-width, initial-scale=1' />
  <title>TempServer</title>
  <link rel='stylesheet' href='//code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css' />
  <link rel='stylesheet' href='main.css' />
  <script src='//code.jquery.com/jquery-1.8.2.min.js'></script>
  <script src='//code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js'></script>
  <script src='//stevenlevithan.com/assets/misc/date.format.js'></script>
  <script src='main.js'></script>
</head>
<body>
  <div id='main' data-role='page'>
    <div data-role='header' data-position='fixed'>
      <h3>Is it hot?</h3>
    </div>
    <div data-role='content'>
      <ul id='list' data-role='listview' data-inset='true'></ul>
      <p id='info'></p>
    </div>
  </div>
</body>
</html>

The Java Script (not minified):

$(document).ready(function () {
    reload();
});

function reload() {
    $.getJSON('list.json', function (data) {
        var items = [];

        $.each(data.list, function (key, val) {
            items.push('<li id="' + val.id + '"><a><h3>' + val.name +
            '</h3><p>' + val.id + '</p><p class="ui-li-aside">' + 
            val.val.toFixed(1) + ' &deg;C</p></a></li>');
        });

        $('#list').html(items.join('')).
            trigger('create').listview('refresh');

        var time = new Date(data.uptime);
        $('#info').html(
            'Uptime: ' + time.format('isoTime') +
            ' (' + data.free + ' bytes free)');
    });

    setTimeout(reload, 10000);
}

The CSS:

.ui-li-aside 
{
    font-weight:bold;
    font-size:xx-large;
}
#info
{
    margin-top:10px;
    text-align:center;
    font-size:small;
}

And the JSON response with the measures:

{
"list":[
{"id":"104938A501080057","name":"Sensor 1","val":16.188},
{"id":"28DA3E95040000CD","name":"Sensor 2","val":0.813}],
"uptime":57430902,
"free":620
}

You can get the full sketch in here: TempServer.ino

The hardware schematic is in my other post: The hardware is ready!

Now I want to utilize the 1KB EEPROM on the processor to store some temperature log and a proper name for each sensor, this will have to come with some more HTML pages to display a nice graph and edit the name for each sensor.
I hope I will have the space, the current code consume 17KB out of the 30KB available.

Thanks.

Thursday 17 January 2013

Arduino Web Server with ENC28J60 + JY-MCU AVR

It took some time and several attempts to find an Ethernet library for ENC28J60 that works on the JY-MCU AVR board using ATmega32.

Hurray, my web server is responding!


The formal Arduino Ethernet Shield and the library to use it are built around the WIZnet W5100 Ethernet controller. The main advantage of the WIZnet W5100 over the Microchip ENC28J60 is the built in TCP/IP stack, that it, it has built in support for 4 sockets and protocols like TCP, UDP, ICMP, IPv4 ARP. While the ENC28J60 only support the physical and link (MAC) layers and the rest need to be implemented in software.

I first started with this library: https://github.com/turicas/Ethernet_ENC28J60
This library goal is to expose the same API as the standard Ethernet library that work with the W5100 and allow developers to choose between W5100 and ENC28J60 without any change to their sketch/code.
After trying the web server example and adding some debug code, I took a deeper look into the library code   to asses the list of limitations it has and how this affect the functionality.
I believe the main challenge for such library is to manage the 4 sockets and their data buffers with the limited memory available on the ATmega32 (2KB) compared to the 8KB buffer on the Ethernet chip.
Even if we split the Ethernet buffer in half (4KB RX + 4KB TX), we might get 4 different 1K packets, one for each socket, and we have no way to store them all in memory for processing. I think this is why the library is limited to one socket at a time, and in that case, what is the point in that library.

I then switched to a different library - EtherShild that is used by Nuelectronics, Andy's Life, and others.
Apparently, I was not the only one that went this road: http://arduino.cc/forum/index.php/topic,22635.0.html
At least now I have a library that works.

To make it work, I had to modify it a bit to use the SPI pin definitions from the pins_arduino.h file so the IDE will take the variant I wrote for the JY-MCU board. For some reason, both libraries assume only the Arduino standard boards instead of using the definitions in the pins_arduino.h or the just use the SPI library.

This library even comes with example to take temperature measurement from a 1-wire DS18B20 digital thermometer and show it on a web page.
I gave it a go, but had to modify it a bit to make it work with DS18S20 that use parasite power and provide readings differently:

  1. Add a strong pull-up  for 750ms between the convert temp instruction to the read instruction by setting the pin to output/high for 750ms.
  2. Change the conversion of the read to match the device resolution.


However, this sample can't handle more than one device on the bus and perform the reading during the respond to the page request and it takes about 750ms to return the page.

Next: use a proper one-wire library that can handle multiple devices on the bus and perform the reading asynchronously to web page requests.

Update: later on, when I continued my 1-wire temperature server development, I switched to another Ethernet library - EtherCard. It has a better API and support DHCP, NTP, UDP, as well as TCP client and server.

Saturday 12 January 2013

The hardware is ready!

The two boards are connected using some cables and connectors I took out of an old PC.

Not yet with the 1-Wire bus (just a pull-up resistor to VCC).

Important: the ENC28J60 runs on 3.3V and the JY-MCU must be set to run on the same voltage (as you can see on the bottom left corner).

The connection use the standard SPI wires/pins (see previous post), reset signal and power (VCC, GND).

Next stop: web server software!


And the schematic:



IMPORTANT!
The 3.3V regulator on the JY-MCU is too small to power up the entire system.

Note for DS18B20: The device VDD pin must be grounded for operation in parasite power mode.

Thursday 3 January 2013

JY-MCU with Arduino IDE

There are some challenges to program the JY-MCU Minimum AVR System Board (ATMEGA32) using the Arduino 1.0 IDE:
  1. It is not a recognized board option, so ports are not mapped correctly.
  2. It is not one of the Arduino chips, it is an ATmega32L, so not sure everything will work properly.
  3. It comes with HID bootloader, so the IDE is unable to download the sketch with avrdude.
To my luck, Arduino IDE is able to work with custom boards: http://code.google.com/p/arduino/wiki/Platforms
This allows me to define the JY-MCU as another board and specify all the available pins and their features.

The board schematic can be found here: JY-MCU Min32 v1.2.pdf
And the files I have created to add it to the Arduino IDE can be found here: JY-MCU.zip
All you need to do is to extract the JY-MCY folder and put it into in the hardware sub-folder of your sketchbook folder (this is the Arduino folder in your Documents on a Windows operating system).

Now I can select the board in the Arduino IDE:

Here is the list of digital and analog pin allocations:

Digital | Analog | Port | Hardware & Functions
--------+--------+------+----------------------------------
 D 0    |        | PD0  | RXD  USB(D+)
 D 1    |        | PD1  | TXD
 D 2    |        | PD2  |      USB(D-)
 D 3    |        | PD3  | 
 D 4    |        | PD4  | SW1  PWM
 D 5    |        | PD5  | SW2  PWM
 D 6    |        | PD6  | SW3
 D 7    |        | PD7  | SW4  PWM
 D 8    |        | PB0  | LED8
 D 9    |        | PB1  | LED7
 D 10   |        | PB2  | LED6
 D 11   |        | PB3  | LED5
 D 12   |        | PB4  | LED4 SPI(SS)
 D 13   |        | PB5  | LED3 SPI(MOSI)
 D 14   |        | PB6  | LED2 SPI(MISO)
 D 15   |        | PB7  | LED1 SPI(SCK)
 D 16   |        | PC0  |      I2C(SCL)
 D 17   |        | PC1  |      I2C(SDA)
 D 18   |        | PC2  | 
 D 19   |        | PC3  | 
 D 20   |        | PC4  | 
 D 21   |        | PC5  | 
 D 22   |        | PC6  | 
 D 23   |        | PC7  | 
 D 24   |  A 0   | PA0  | 
 D 25   |  A 1   | PA1  | 
 D 26   |  A 2   | PA2  | 
 D 27   |  A 3   | PA3  | 
 D 28   |  A 4   | PA4  | 
 D 29   |  A 5   | PA5  | 
 D 30   |  A 6   | PA6  | 
 D 31   |  A 7   | PA7  | 

Notice that due to the differences between the ATmega328 on the Arduino boards and the ATmega32 on the JY-MCU board, not all libraries are supported. For example, the SoftwareSerial library use pin change interrupts that are not available in the ATmega32, so the library will not work.

Now I can build some code (for instance, the Blink example), but I can't program the board (upload the *.hex) directly from the IDE.

The JY-MCU board comes with an HID bootloader and this bootloader is not supported by the AVRDUDE tool that the Arduino IDE is using.

For now, I just build my code (use the Verify / Compile menu option / button) and use HDIBootFlash to upload the *.hex file to the board. After the build the *.hex file can be found in the temp files directory (on Windows: C:\Users\<user>\AppData\Local\Temp).
I hope that in future versions of Arduino it will support custom tools for uploading code to the board and I can integrate some HID bootloader tool.
Another option is to put a different bootloader on the board, one that is supported by AVRDUDE, like USBaspLoader, but for this I need a programmer hardware that I don't have at the moment.

Now to my next task: make a web server using ENC28J60 Ethernet Module.

Update (27/01/2012): I wrote a small VBS script to make it easier to upload the *.hex file to the board.
The script finds the latest *.hex file in my temp directory (this is the result of verifying the sketch in Arduino IDE), prompt to continue and then use HIDBootFlash.exe to upload it to the board.
You can get the script here: UploadHex.vbs (rename the file to UploadHex.vbs).
You need to edit the following line with the location of your HIDBootFlash.exe:
shell.ShellExecute "C:\Dev\arduino-1.0.3\HIDBootFlash.exe", " -r " & hex.Path