RSS

Reading I2C Sensor Data with the Oak

April 1st, 2016 • Electronics, ESP8266, Internet of Things, Software Development2 Comments »

The weather station project will be bringing together a number of sensors, light, ultraviolet light, air pressure, humidity, wind speed, wind direction and rain fall. This collection of sensors falls into three groups:

  • Electronic sensors on an I2C bus
  • Mechanical sensors using switches
  • Analog sensors

The current plan is for the weather station to use the Oak as the microcontroller running the show. The data from the sensors can then be uploaded to the cloud, destination to be determined, but let’s start with Sparkfun’s data service.

The I2C sensors will require the least amount of work to get up and running so let’s start with those. The two sensors operating on the I2C bus are:

Oak and  2C Sensors on Breadboard

Oak and 2C Sensors on Breadboard

One of the great things about working with these two sensors is the fact that there are prebuilt drivers and example code for both breakout boards available from Github. What could be simpler, well head over to the Sketch – Include Library – Board Manager… menu in the Arduino IDE and you can download the library and have the IDE install it for you.

TSL2561 – Luminosity Sensor

This sensor allows the radiance of the light to be calculated in a way that approximates the response of the human eye. It does this by combining the input from two photodiodes, one infra-red only and one visible light and infra-red light combined. The output from the two sensors can be used to luminous emittance in lux (lumens per square metre).

The following table gives an idea of the lux values for typical scenarios:

Lux Typical Environment
0.0001 Moonless, overcast night sky
0.002 Moonless clear night sky
0.27–1.0 Full moon on a clear night
80 Office building hallway
320–500 Office lighting
1000 Overcast day
10000–25000 Daylight

As you can see from the table above, the lux values for a “normal” human day can vary dramatically. The sensor copes with this by allowing the use of a variable time window and sensitivity when taking a reading. Effectively the sensor accumulates the readings over the time window (integration interval) into a single 16-bit number which can then be used to calculate the lux reading.

BME280 – Air Pressure, Temperature and Humidity Sensor

This sensor is produced by Bosch and is packaged in both I2C and SPI configuration on the same board. The accuracy of the sensor appears good, pressure and temperature both to 1% and humidity to 3%.

Libraries

Both Sparkfun and Adafruit have provided libraries and example code for the boards. These were easy to add to the development environment.

One caveat, the BME280 requires the addition of the Adafruit sensor library as well as the BME280 library.

Once added it was a simple case of wiring up the sensor to 3.3V and the I2C bus and running the example code.

They both worked first time.

Some Code Modifications (for later)

The light sensor has been show to work in low light conditions but not to any degree of precision. A possible modification to the example code is to look at the sensitivity and integration window settings to see if the precision can be adjusted to make the sensor return better readings in low light.

Some of the values when calculated use the fractional part of a floating-point number, temperature and humidity spring to mind. This meant adding a method to convert a double into it’s string representation for debugging purposes. Trivially solved but an annoying omission from the implementation of sprintf.

Posting to Particle Dashboard

The Oak can also post to the Particle dashboard providing a second method of debugging your application. Statements such as Particle.publish(“Debug”, “Temperature data…”); will cause the string Temperature data… to be posted in a group/attribute Debug

So the readings from the office look like this:

Some Weather Data

Some Weather Data

Conclusion

Two simple to use sensors with good supported class libraries make these sensors quick and easy to hook up to the Oak. Merging the two examples was simple and sensor data is now appearing over the serial output from the Arduino.

Compiling the code gives some warnings about the I2C library being compiled for the ESP8266 whilst the target board is defined as an Oak. This can be ignored as the Oak is really a convenient wrapper around an ESP8266 module.

Next up, some analog sensors to measure ultraviolet light and wind and rain properties.

Setting Up the Oak – Flashing LED

March 27th, 2016 • Electronics, ESP8266, Internet of Things, Software DevelopmentComments Off on Setting Up the Oak – Flashing LED

The Oak microcontroller is new, Digistump only shipped version 1 firmware a few days ago (20th Match 2016). The hardware I have was shipped sometime in January. So the first thing to do is to upgrade the firmware and then try blinking an LED.

Upgrading the firmware

The Digistump Wiki contains a number of tutorials and troubleshooting guides. First stop the Connecting Your Oak for the First Time page. This shows how the Oak can be connected to your WiFi network and the firmware updated.

The initial over the air firmware update was problematic to say the least. Reading through the Digitsump forums it seems that I am not the only one having a problem with the first update. There are three methods for upgrading the firmware:

  • Over the Air using firmware from the internet
  • Over the air with a local server
  • Serial using pyserial or esptool

I started at the top of the list and slowly worked my way down. In the end the only method that worked for me was the serial update.

Flashing an LED

With the latest version of the firmware installed it is time to test the development environment. What could be simpler than flashing and LED. The on board LED is connected to pin 1 so lets try and use that.

Digistump offer two development environments:

At the time of writing there was a known issue with the Particle development environment which prevented an application being built and flashed successfully. This is an early release and so issues are expected.

This only leaves the Arduino environment, an IDE I really hate.

There are two methods for flashing an application to the Oak using the Arduino environment:

  • Over The Air (OTA)
  • Serial (requires Python)

Despite the earlier problems with the firmware update I decided to try the OTA method first. DigitStump have provided compehensive instructions in their WiKi on how to achieve this.

Following the example was easy and after only 15 minutes I have the LED on the Oak flashing at 1Hz. Just to prove it was not a fluke I then tried changing the frequency and reflashing the Oak.

Success!

Conclusion

My initial frustration with the firmware update was soon forgotten once I had an application successfully running on the Oak. I am hoping that the issues were caused by the fact I have an early release of the board with the original firmware installed.

Programming is easy enough and can be done over the air which is convenient.

Next up, talking to sensors.

Weather Station

March 25th, 2016 • Electronics, ESP8266, Software DevelopmentComments Off on Weather Station

The first part of this year has seen me working on some photography projects, now time to get the soldering iron out. I have three projects I’m hoping to complete this year and one long term project that may take me a while, so pay attention 007.

Weather Station

A few weeks ago I received a couple of Oaks. These boards are based around the ESP12 module, a Kickstarter project I backed at the end of 2015. The project aimed to make working with the ESP12 easier by providing integration with particle.io. The latest firmware was release a few days ago so I think it is time to give this little device a go.

At the start of the year we came across a weather meter which allowed the measurement of rainfall, wind speed and wind direction. My wife mentioned that it might be nice to use one of these to record the weather in the garden.

And so the idea was born, weather meter, meet the Oak.

Mapping Out The Project

After a few hours the project started to become larger than just a couple of sensors, it currently looks something like the following:

Weather Station Mind Map

Weather Station Mind Map

I have coloured each block of concepts the same colour in order to give the project some structure. Let’s look at each block in turn and see how we can approach the problem.

Temperature, Pressure and Humidity

Starting with the green block and five o’clock on the diagram.

Temperature, Presure and Humidity Mind Map

Temperature, Presure and Humidity Mind Map

There are two temperatures we can measure here, air temperature and soil or ground level temperature. The air temperature will give an indication of how pleasant a day it is at the moment and the ground level sensor will give an indication of the progress of the seasons from the plants perspective. For this reason we are interested in both of these measurements.

Air pressure has long been used as a predictor for upcoming weather events.

Luckily we can get the air temperature, pressure and humidity sensor in one convenient package, the BME280. Ground level temperature will need a waterproof sensor. I think this would be best purchased as a unit rather than made so the DS18B20 with a 6 foot cable looks like it might be ideal.

Wind and Rain

Working clockwise, the next block are the wind and rain sensors:

Wind and Rain Sensor Mind Map

Wind and Rain Sensor Mind Map

All of these measurements come from the weather meter. The wind speed and rainfall sensors are simple switches that generate pulses whilst the wind direction is a resistor network.

Light Sensor

The next block shows the two light sensors:

Light Sensor Mind Map

Light Sensor Mind Map

The two light measurements are the overall light intensity (luminosity) and ultraviolet light intensity. Luckily there are a couple of sensors for these two measurements, the TSL2561 and the ML8511.

The ultraviolet light sensor is an analogue sensor and so we will have to consider the stability of the supply voltage when making the reading.

The luminosity sensor uses a measurement window and a sensitivity setting to take a reading. This means that for given settings the sensor may be overwhelmed and simply give a maximum reading. The work around for this is to make the measurement window and sensitivity dynamic. So long, sensitive windows at night and short less sensitive windows on bright sunny days.

Cases and Location

The next things we need to consider are cases and locations:

Case and Location Mind Map

Case and Location Mind Map

The microcontroller and power etc. will need to be located in a case of some form. This will need to be weather proof as water and electricity are not the best of friends. It would also be a good idea to keep any batteries in an environment with a reasonably stable temperature. A little research into how the professionals house weather Stations.

The sensors on the other hand need to be outdoors in a suitable location for the measurements being taken.

Power Supply

All of this equipment will need a stable power supply:

Power Supply Mind Map

Power Supply Mind Map

The initial work can be done using a bench power supply but when the project moves outdoors it will need to either be mains or battery powered. The long term aim is to use a solar cell and rechargeable battery, as they say on Kickstarter, a stretch goal.

Data Logging and Real Time Clock

Now we have collected all of this information we need to do store it somewhere:

Data Logging Mind Map

Data Logging Mind Map

The Oak is a WiFi enabled board so the most obvious place to put the data is the cloud. It might be an idea to also provide some local storage in case the WiFi network is unavailable.

The Real Time Clock (RTC) could have two uses, to wake the microcontroller and also provide a timestamp for the data items.

Conclusion

What started out as a simple wind and rain logging project has grown a little. The current specification is to measure and log the following readings:

  1. Rainfall
  2. Wind speed
  3. Wind direction
  4. Luminosity
  5. Ultraviolet light

The measurements should be collected and reliably logged either locally or preferably to the cloud.

There are several challenges with a number of interesting problems to overcome.

Let’s get this show on the road.

So I’m Sneaky

March 6th, 2016 • PhotographyComments Off on So I’m Sneaky

So it’s official, I’m sneaky. That’s what I have been told by my wife, Karen. Why you may ask, well not all of my projects are electronic or software related; I’m also a keen, average amateur photographer.

Flying Scotsman

Restoration on the Flying Scotsman was finally completed this year. This was a long term project after the locomotive was purchased for the nation by the National Railway Museum. The train re-entered service with a run from London to York in February 2016.

As part of the return, the National Railway Museum organised a couple of photo opportunities, one early in the morning and one in the evening when it was dark. In both cases the locomotive would be under light steam and the evening shoot would be atmospherically lit. Now I’m not a train enthusiat per se but as a photographer how could I resist.

Here are a couple of the photos from that evening:

Flying Scotsman in North Yard

Flying Scotsman in North Yard

And a low shot:

Flying Scotsman in North Yard Low Shot

Flying Scotsman in North Yard Low Shot

But that does not explain the sneaky…

Family Photographs

My wife’s family have always been very close but sadly her mother and father are no longer with us. We do have a collection of about 300 photographs from her mothers family collection. Unfortunetly they are in mixed condition, some of them rather poor. The photographs had a variety of problems from creases to marks and tears on the surface of the image. For example, the following is a snippit from one of the images:

Unprocessed Image With Creases

Unprocessed Image With Creases

Time for some restoration work. Modern image software is very impressive and not always expensive. The software I tried (and later purchased) last year is Mac specific, there is no PC version, and won Mac application of the year for 2015. The software is Affinity Photo. This software offers an impressive set of features and the video tutorials provide a new user with an insight on how to use the features.

So taking the image from above and 30 minutes with the software and I had the following:

Processed Images With Creases Removed

Processed Images With Creases Removed

Creases all gone, now on to improving the image a little.

Still no sign of sneaky…

Starting in January, I methodically took each of the 300+ images and started to restore the full collection. A few of the images were in too poor condition or out of focus and so they were discarded but the majority of the images could be improved a little. Six weeks later I had a comprehensive set of photographs going back to Victorian times.

The final stage of the processing was the creation of a family album starting with from Great Grandparents through to the current day. For this I used Boots Photo Service to create an 11×8 inch hardback album.

And that’s why my wife thinks I’m sneaky.

Conclusion

It has been a while since I was able to use the soldering iron and if I am to get through the projects planned for Christmas then I need to pick it up again. The time playing with Affinity Photo has certainly proved fruitful, I can well recommend this product.

The brief diversion into image processing did however bring a moment of pleasure into my wife’s life, a moment I’ll always treasure.

Projects for 2016

January 31st, 2016 • General2 Comments »

The Christmas break always gives time to plan the coming years projects. Like all hobbyists I’m sure that I’m going to be planning far more projects than I have time to complete. One thing that I am going to try and do is complete some of the projects from former years.

LED Cube

So let’s start with the LED cube. This project started a while ago and the electronics and software worked well but the LEDs have ended up sitting on a shelf for a few years. The aim was to house the cube in a suitable case but for some reason this was never really completed.

Time for a change.

The first step in the completing the project is to connect the LED cube to a base board. The board would provide the power to the LEDs, nothing more, just power to the LEDs. The design utilised a simple transistor circuit to turn the LEDs on or off. A pull-down resistor ensures that the default situation for the switch will be the off position:

Transistor LED Schematic

Transistor LED Schematic

Multiply this by 64 and you have the base board for the LED cube. The PCB layout looks like this:

LED Cube Base Board Layout

LED Cube Base Board Layout

The board design was sent for manufacture in early-mid December. This is by far the largest (although not the most complex) design I have had made. The board was 20cm x 20cm. The final boards arrived just before Christmas:

The top of the board has 64 pads laid out in a grid for the LEDs:

LEDBaseBoardTop

The bottom of the board has 64 copies of the power circuit above:

LED Base Board Power Circuit

LED Base Board Power Circuit

When I was applying the solder paste to this board I was wishing I could afford a solder mask. After building a couple of power circuits it occurred to me that a simple mask could be made using an overhead acetate (remember these from the 1980s/90s) and a dremel. It does not matter that the holes in the mask would be circular, only that they are in the correct position. A 1mm diameter drill bit in a dremel and a piece of acetate provide the right amount of solder paste to the board.

A tip for the future.

The next step was to mouth the LEDs. Easier said than done. The cube had already been assembled and so the legs of the LEDs had to be coaxed into position. Several hours later we have:

LEDs On Base Board

LEDs On Base Board

Soldering on some connectors allows a quick check of each LED in the cube. It works 🙂

Next step is to look at the control circuitry.

Other Plans

As well as completing the cube, there are a few other projects that are in the pipeline:

  • Christmas jumper for a friend – adding some lights, we all love LEDs
  • Get to grips with FPGAs
  • Docker and Vagrant – I know Vagrant can help me with ESP8266 development
  • ESP8266, ESP32?, Photon, Oak and RedBear Duo – There is going to be a lot of IoT in 2016
  • Complete the wireless infra-red remote control

2016 – time to complete some projects and start some new ones.

PiZero – Is it a Zero or Hero

December 6th, 2015 • Raspberry PiComments Off on PiZero – Is it a Zero or Hero

On 26th November the Raspberry Pi foundation announced the release of the PiZero, a $5 computer based upon the Broadcom 2835 processor. Looks like it could be interesting…

First Impressions

The board itself is about 60% the size of a credit card and has a reduced number of input output options compared to the other Raspberry Pis in the range but promises more processing power than the original Raspberry Pi. A quick look at the specifications reveals the following:

  • Broadcom BCM2835 processor (1GHz ARM11 core – 40% faster than the original Raspberry Pi)
  • 512MB of SDRAM
  • A micro-SD card slot
  • A mini-HDMI socket
  • Micro-USB sockets, one for data and one for power
  • An unpopulated 40-pin GPIO header (Identical to the Model A+/B+/2B)

The form factor and price combined are sure to make this ideal for the hobby/hacker market.

Extras

Some hobbyists are sure to have the additional connectors in their parts bucket, but not this one, every other cable you can think of but not the OTG or HDMI convertor! Over the years I have collected a fair number of cables and other spare parts but none are suitable for the PiZero. The micro-SD cards I have in abundance but the additional connectors needed to start work are another matter. In hindsight I should have ordered the additional cables when purchasing the PiZero from Pimoroni as these were on offer for £8 at the time of ordering.

Hindsight is a wonderful thing…

The PiZero arrived in short order, the accessories were another matter. It is not often that Amazon let me down but this was one of those times. A small pause while waiting for delivery.

Setting up the PiZero

Setting up the PiZero was as simple as the initial setup for the rest of the Raspberry Pi family. The easiest option is to use NOOBS. This just needs a formatted SD card, 16GB should do it.

Formatting the SD card and dropping NOOBS on the card took about 5 minutes, now time to finally power on the Raspberry Pi. But first a few connections, the HDMI was connected through a standard HDMI cable through a convertor to the the mini-HDMI. My USB hub was connected through an ingenious USB OTG Convertor. Keyboard, trackball and WiFi dongle were added to the hub. We’re now ready to go.

NOOBS starts to the desktop by default and so the mini-HDMI connection is essential. The board started reasonably quickly although users of the Raspberry Pi B+ etc will find the start up a little slow.

The first things NOOBS did was to reorganise the file store, this takes about 30 minutes.

The next step, booting to the desktop and the first thing to do, configure the system to boot to the command line and setup the network settings for the WiFi.

And then reboot.

One hour after starting the process I had a PiZero on the network connecting to the command line via SSH.

Conclusion

The PiZero created a fair amount of excitement at work but for what are probably the wrong reasons. The initial excitement about the $5 price tag soon starts to wane when you start buying the add-ons. Don’t get me wrong this board has a purpose, this is a fine low cost hackers board. My concern is the number of people thinking that this is a low cost home computer for the family. If you want a low cost family Raspberry Pi then buy the Raspberry B2/B+ as these will be far easier to connect to the kit most families are likely to have in the home.

So where does the PiZero fit in. Well I think this is really a good fit for the market the compute module market. The compute module was always going to be a pain to work with for the hobbyist and the full Raspberry Pi is too large for some applications (quadcopters etc). The PiZero fits nicely into this market. Getting the additional components (OTG cables etc) is a one off cost for the hobbyist embedding a PiZero into a project. This is where I think this board will fit nicely.

So, in conclusion, great for the hobbyist hacker but for families wanting to get kids into computing I’d go for the Raspberry Pi B2/B+ as it’s going to be far easier to get connected.

LED Board Has Arrived

November 1st, 2015 • ElectronicsComments Off on LED Board Has Arrived

A few weeks ago I started to work with KiCAD and put together a small LED board as a project to become familiar with the application. The boards were sent to manufacture and the the postman delivered the manufactured PCBs yesterday.

LED Board Front

LED Board Front

LED Board Front

LED Board Front

Time to add the components and test the boards.

Populated Board Right Angled Headers

Populated Board Right Angled Headers

And one with straight headers:

Populated Board Straight Headers

Populated Board Straight Headers

Everthing looks good, the boards work OK so time to move on to the big board for the cube.

Moving to KiCAD

October 25th, 2015 • Electronics1 Comment »

I have been a long time supporter of DesignSpark PCB for laying out my PCBs. Moving to the Mac meant that I had to look for an alternative or to use the PC emulator. Enter KiCad.

I needed a project in order to evaluate KiCAD, something small and inexpensive to manufacture will fit the bill. One project that needs completing is the LED cube. The 74HC595s in this project were always going to restrict the power of the cube. They have a limit of 125mW which limits either the number of LEDs that can be illuminated or the brightness of the LEDs. This can be easily overcome by either using a higher power 74HC595 or by connecting each of the LEDs to a transistor wired as a switch. The transistor as a switch idea gives some flexibility for future experimentation and so this is the direction we will take. Making this board for the cube would be expensive as it would be large, over 15cm x 15cm. A smaller version would prove the concept as well as the software.

8 LED Indicator Board

The 8 LED Indicator Board is a simple PCB containing all of the components that would be used in a large powered board. The board is simple, it takes a signal for each of the 8 LEDs, power and ground. Any high signals turn the transistor on and illuminates the appropriate LED. The schematic for a single switch is as follows:

Simple Transistor Switch

Simple Transistor Switch

The board contains 8 of these switches along with connectors for the power and signals, adding seven more and some connectors gives the following:

8 Transistor Switches

8 Transistor Switches

The next step in the process is to convert this design to a PCB layout. Normally (with DesignSpark) I would just jump from the schematic straight to the PCB layout. With KiCAD it is necessary to perform two additional (for me) actions. The first is to annotate the components in the schematic. The second is to associate a footprint to each of the components. PCB layout can commence once this has been completed.

A few hours later:

8 LED Transistor Switch PCB Layout

8 LED Transistor Switch PCB Layout

There is even a 3D viewer with an impressive set of models built in:

8 LED Switch in 3D

8 LED Switch in 3D

So far, so good, the final step is to generate the gerbers, send for manufacture and wait.

Conclusion

Moving from one software suite to another is always an interesting process. Old habits such as key strokes, menu locations etc are difficult to break. I certainly found some aspects of KiCAD a little frustrating but as ever, there is always Google.

The gerber files have been sent to manufacture. The good news is that they were accepted straight away and have been through the manufacturing process. They are currently somewhere between China and the UK. I expect to see them in about 1 week (assuming the usual delay between ordering and shipping).

There are some issues I have found with the software:

  • The PCB Designer drains the battery on the Mac significantly faster than the Schematic layout tool.
  • Every now and then the PCB layout tool will start to zoom in (or out) seemingly at random.
  • Creating a new, empty component library is not as intuitive as it could be.

In fairness though there are some thing which I really did like:

  • Schematic editor is simple to use
  • Large component library
  • 3D Viewer
  • Easy to create new components
  • It only took a week to go from nothing to gerbers

All in all, this has been a positive experience although painful at times. The only thing remaining is to see how the boards turn out.

Going Over to the Dark Side

August 10th, 2015 • General2 Comments »

Finder and Visual Studio

The last few weeks has been busy but not with hardware, the STM8, STM32 and the Netduino have all been idle. It has however been an interesting month as I have been moving from PC development on to a Mac.

The Dark Side Beckons

Every few year I upgrade the home hardware set up. Slowly over the years these upgrades have become more costly to the point where light-weight portable PCs have approached the cost of equivalent Apple products. Add to this the fact that I also do some iPhone/iPad development and need an Apple machine the cost difference starts to become even smaller, in fact they nearly disappear.

This last few months has seen the time for the periodic renewal of the home IT system. Given the cost differences becoming smaller I had to consider Apple as a viable option.

Conflicting Demands

So what do I really need?

  1. Visual Studio
  2. iPhone/iPad/Mac development
  3. Netduino development
  4. STM8S development
  5. STM32 development
  6. ESP8266 development

Some of the above require access to Windows, certainly Visual Studio requires Windows, some have Mac options available (STM32 for example), some have only Windows solutions. There are several options for running Windows on a Mac but no supported ways of running OSX on a PC.

Windows can run on a Mac natively or in a virtual machine. Several options are available, BootCamp for a native implementation and VirtualBox, Parallels offer a virtualised option. Parallels is attractive as it offers coherence mode. This allows a Windows application to appear on the Mac desktop in a Window on the Mac desktop.

The only major concern now is compatibility, hardware compatibility. Some of the tools are only really available for Windows, alright either easily available for Windows or only available for Windows.

Let’s start with Visual Studio and Netduino. The recent release of Visual Code does not really make up for the wealth of tools available within Visual Studio. Netduino is a C# development environment and so this is really restricted to Visual Studio. The good news is this works well under Parallels.

The IAR development environment for the STM8S is currently only available for Windows.

Development environments for STM32 are available for both Windows and Mac. VisualGDB provides a convenient method of programming the STM32 under Windows using Visual Studio. There are several tutorials available discussing the use of Eclipse to work with the STM32, so which works and more importantly, which is more convenient?

ESP8266 can be programmed using the Arduino IDE. The board can be added using the board manager. This means that the board can be programmed from a Windows or Mac environment.

The Xamarin tools for Visual Studio is an area I wish to research and use in the future. These tools require both Windows and OSX systems.

Initial investigation indicates that using a Mac may be an option.

Virtualisation

Reviewing the criteria above it is obvious that Windows needs to be installed on the Mac either natively, dual booting or virtualised.

The native installation would offer some benefits like having the entire machine resources available but this would make Xamarin development difficult as Visual Studio needs access to a Mac as a build server.

The option finally selected was Parallels as this allows Windows to run either as a virtualised machine in a window or to allow Windows applications to run as individually as windows on the OSX desktop.

New Software Challenges

There have certainly been some new software challenges. Moving from SQL Server to MySQL has been interesting to say the least.

Notepad++ is one tool which has been missed but there are Mac alternatives (TextWrangler and Sublime spring to mind).

Macs don’t get viruses do they!!! Not falling for that one. Luckily my ISP (BT) provides AV free of charge using McAfee’s products. I thought this would be an issue but no, there is an OSX version of McAfee’s tools available and best of all it’s “free” to me.

Backups have been made challenging as the Mac can currently read NTFS file systems but cannot write to them. All backups should be encrypted in case they are lost. Alright, only some data is sensitive, bank statements, etc. should certainly be hidden away from view. You could argue that the music collection is not really sensitive but as this is all tied up with iTunes then encryption is needed.

Conclusion

So how did the experience go? Well so far everything seems to have gone well. All of the necessary tools are installed and running as expected.

An early decision to use OSX native tools where possible in preference to Windows tools has made life interesting at times. The STM32 development environment has been challenging to set up on the Mac. The Windows option using VisualGDB seems to be the best option so far.

The Mac chosen was the MacBook Pro. There has been a major advantage using this machine over a laptop, fan noise. The old laptop was noisy, the fans started as soon as any real load was placed on the machine. The MacBook is silent by comparison, in fact no, the new MacBook is silent most of the time. The few times I have heard the fans start have usually coincided with Windows running.

It has been an interesting few weeks, well nearly six weeks but the system is up and running. Next stop, some more hardware development.

UDP on the ESP01 (ESP8266 Development Board)

June 1st, 2015 • Electronics, ESP8266, Internet of Things, Software DevelopmentComments Off on UDP on the ESP01 (ESP8266 Development Board)

ESP8266 boards offer an amazing opportunity to explore the IoT world at a low cost. The boards start for as little as £5 here in the UK and come in a variety of form factors from one with only two GPIO pins to larger boards containing more GPIOs, PWM, I2C, SPI and analog capability. The boards started to become noticed around the middle of 2014 and have become more popular as the tools and documentation have matured.

Support for the boards is mainly through the online community forum. The latest documentation and SDKs can be found through the same forums.

The boards make low cost networks of sensors a possibility with the ESP8266 modules acting as either small servers or clients on your WiFi network.

The ESP8266 module is often supplied with one of two firmware version burned into the module:

  1. nodeMCU – Lua interpreter
  2. AT command interpreter

For the purposes of this exercise we will look at replacing the default firmware supplied with a custom application.

The SDK available from Expressif allows the developer to program the module using C. First thing to do is to install the tool chain for the module. The ESP8266 Wiki contains a host of information including instructions on setting up the tools on a variety of platforms. This whole process took about 2-3 hours on my Windows PC with another few hours to put together a template for a makefile application for Visual Studio.

Now that the development tools are in place we can start to think about the sensor network. Security is a major concern for Internet of Things (IoT) projects but this proof of concept will ignore this for the moment and rely on the WiFi encryption as the only mean of securing the data. This is a proof of concept afterall.

The applications developed here will allow data to be transmitted using UDL over the local area network.

UDP Receiver

Before starting on the ESP8266 application we should put together a simple application to receive the data from the local network. A simple .NET application on a Windows PC should do the trick:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace UDPConsoleClient
{
    class Program
    {
        static UdpClient _udpClient = new UdpClient(11000);

        static void Main(string[] args)
        {
            Console.WriteLine("UDP Client listening on port 11000");
            IPEndPoint _remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); 
            while (true)
            {
                byte[] data = _udpClient.Receive(ref _remoteEndPoint);
                string message = Encoding.ASCII.GetString(data);
                Console.WriteLine("Message ({0}): {1}", _remoteEndPoint.Address.ToString(), message);
            }
        }
    }
}

Create a new Windows console application on the PC and add the above code to the program.cs file. When run, this application will listen to the local network and display any UDP packets as a string to the console. Nothing special but good enough for the purposes of this experiment.

Basic ESP8266 Application

The basic ESP8266 application works in a similar way to an Arduino application, there is an initialisation method user_init and a loop method. The loop method is slightly different from the Arduino loop in that it is added to a task queue and the developer is free to select the name of the method. A basic application looks something like this:

#include "at_custom.h"
#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#include "os_type.h"
#include "mem.h"
#include "user_config.h"
#include "ip_addr.h"
#include "espconn.h"
#include "user_interface.h"

#define USER_TASK_PRIORITY          0
#define USER_TASK_QUEUE_LENGTH      1

//
//  Callbacks for the OS task queue.
//
os_event_t userTaskQueue[USER_TASK_QUEUE_LENGTH];

//
//  User function which will be added to the task queue.
//
static void ICACHE_FLASH_ATTR UserTask(os_event_t *events)
{
    os_delay_us(10);
}

//
//  Initialise the application and add the user task to the task queue.
//
void ICACHE_FLASH_ATTR user_init()
{
    //
    //  Start OS tasks.
    //
    system_os_task(UserTask, USER_TASK_PRIORITY, userTaskQueue, USER_TASK_QUEUE_LENGTH);
}

Compiling and deploying this application will result in a module which does nothing much other than wait.

Debugging

Unlike some of the other modules and boards discussed on this blog, the ESP8266 does not have much available in the way of debugging. Code will need to be added to the application to output debug information on GPIO pins in order to get feedback on what is going on inside the application.

The ESP01 module being used has two GPIO pins available, GPIO0 and GPIO2. We can use these to output serial data akin to SPI and then use a logic analyser to examine the application state. Adding the code below will allow us to do this.

#define BB_DATA                     BIT0
#define BB_CLOCK                    BIT2

//
//  Initialise the GPIO pins.
//
void InitialiseGPIO()
{
    gpio_init();
    //
    //  Set GPIO2 and GPIO0 to output mode.
    //
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
}

//
//  Bit bang the data out as serial (SPI) data.
//
void BitBang(uint8 byte)
{
    //
    //  Set the clock and data bits to be low.
    //
    gpio_output_set(0, BB_DATA, BB_DATA, 0);
    gpio_output_set(0, BB_CLOCK, BB_CLOCK, 0);
    //
    //  Output the data.
    //
    short bit;
    for (bit = 7; bit >= 0; bit--)
    {
        if (byte & (1 << bit))
        {
            gpio_output_set(BB_DATA, 0, BB_DATA, 0);
        }
        else
        {
            gpio_output_set(0, BB_DATA, BB_DATA, 0);
        }
        gpio_output_set(BB_CLOCK, 0, BB_CLOCK, 0);
        gpio_output_set(0, BB_CLOCK, BB_CLOCK, 0);
    }
    //
    //  Set the clock and data bits to be low.
    //
    gpio_output_set(0, BB_DATA, BB_DATA, 0);
    gpio_output_set(0, BB_CLOCK, BB_CLOCK, 0);
}

Timers

For the proof of concept the application can simply generate a regular packet of data emulating the presence of sensor data. The most cost effective (in terms of power) way of doing this will be to use a timer of some sort.

//
//  OS Timer structure holding information about the timer.
//
static volatile os_timer_t timerInformation;

//
//  Timer function called periodically - try communicating with the world.
//
void TimerCallback(void *arg)
{
    BitBang(0x01);
}

//
//  Initialise the application and add the user task to the task queue.
//
void ICACHE_FLASH_ATTR user_init()
{
    InitialiseGPIO();
    //
    //  Disarm timer.
    //
    os_timer_disarm(&timerInformation);
    //
    //  Set up timer to call the timer function.
    //
    os_timer_setfn(&timerInformation, (os_timer_func_t *) TimerCallback, NULL);
    //
    //  Arm the timer:
    //      - timerInformation is the pointer to the OS Timer data structure.
    //      - 1000 is the timer duration in milliseconds.
    //      - 0 fire once and 1 for repeating
    //
    os_timer_arm(&timerInformation, 1000, 1);
    //
    //  Start OS tasks.
    //
    system_os_task(UserTask, USER_TASK_PRIORITY, userTaskQueue, USER_TASK_QUEUE_LENGTH);
}

Adding the above code to the basic application should generate data on GPIO0 and GPIO2 every second.

UDP Communication & WiFi Connectivity

The last part of the puzzle is to connect the board to the local WiFi network and to start to send data across the network.

WiFi Connection

For a basic WiFi connection where the router is providing a DHCP service then we need to let the firmware know the SSID of the network we wish to connect to and the password for the network:

const char ssid[32] = "--- Your SSID Here ---";
const char password[32] = "--- Your Password Here ---";
struct station_config stationConf;

wifi_set_opmode(STATION_MODE);
os_memcpy(&stationConf.ssid, ssid, 32);
os_memcpy(&stationConf.password, password, 32);
wifi_station_set_config(&stationConf);

Executing the above code will set the network parameters. The network connection is not established immediately but can take some time to become active. Network connectivity can be detected by the following code snippet:

struct ip_info info;

wifi_get_ip_info(STATION_IF, &info);
if (wifi_station_get_connect_status() != STATION_GOT_IP || info.ip.addr == 0)
{
    // Not connected yet !!!
}

UDP Communication

Network communication needs a connection structure to be set up. This holds information about the network connection type, IP addresses and ports. For this exercise we are using the UDP protocol and will broadcast the data to any UDP listener on the network. The UDP broadcast address is x.y.z.255, in this case 192.168.1.255. The code to set this up is as follows:

struct espconn *_ptrUDPServer;
uint8 udpServerIP[] = { 192, 168, 1, 255 };

//
//  Allocate an "espconn" for the UDP connection.
///
_ptrUDPServer = (struct espconn *) os_zalloc(sizeof(struct espconn));
_ptrUDPServer->type = ESPCONN_UDP;
_ptrUDPServer->state = ESPCONN_NONE;
_ptrUDPServer->proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp));
_ptrUDPServer->proto.udp->local_port = espconn_port();
_ptrUDPServer->proto.udp->remote_port = 11000;
os_memcpy(_ptrUDPServer->proto.udp->remote_ip, udpServerIP, 4);

The application can now start to send data over the network:

#define USER_DATA                   "ESP8266 - Data"

espconn_create(_ptrUDPServer);
espconn_sent(_ptrUDPServer, (uint8 *) USER_DATA, (uint16) strlen(USER_DATA));
espconn_delete(_ptrUDPServer);

The application should really perform some diagnostics in the above code in order to detect any errors and clean up where necessary.

Putting it all Together

A little rearrangement of the snippets above is necessary in order to put together a mode elegant solution, namely:

  1. Output the results of function calls to the network to the GPIO pins
  2. check for network connectivity before calling the network functions

Adding these modifications to the code gives the following final solution:

// ***************************************************************************
//
//  Basic UDP broadcast application for the ESP8266.
//
#include "at_custom.h"
#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#include "os_type.h"
#include "mem.h"
#include "user_config.h"
#include "ip_addr.h"
#include "espconn.h"
#include "user_interface.h"

#define USER_TASK_PRIORITY          0
#define USER_TASK_QUEUE_LENGTH      1
#define USER_DATA                   "ESP8266 - Data"
#define BB_DATA                     BIT0
#define BB_CLOCK                    BIT2

//
//  Callbacks for the OS task queue.
//
os_event_t userTaskQueue[USER_TASK_QUEUE_LENGTH];
struct espconn *_ptrUDPServer;
uint8 udpServerIP[] = { 192, 168, 1, 255 };

// ***************************************************************************
//
//  Forward declarations.
//
static void UserTask(os_event_t *events);

//
//  OS Timer structure holding information about the timer.
//
static volatile os_timer_t timerInformation;

//
//  Initialise the GPIO subsystem.
//
void InitialiseGPIO()
{
    gpio_init();
    //
    //  Set GPIO2 and GPIO0 to output mode.
    //
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
}

//
//  Bit bang the data out as serial (SPI-like) data.
//
void BitBang(uint8 byte)
{
    //
    //  Set the clock and data bits to be low.
    //
    gpio_output_set(0, BB_DATA, BB_DATA, 0);
    gpio_output_set(0, BB_CLOCK, BB_CLOCK, 0);
    //
    //  Output the data.
    //
    short bit;
    for (bit = 7; bit >= 0; bit--)
    {
        if (byte & (1 << bit))
        {
            gpio_output_set(BB_DATA, 0, BB_DATA, 0);
        }
        else
        {
            gpio_output_set(0, BB_DATA, BB_DATA, 0);
        }
        gpio_output_set(BB_CLOCK, 0, BB_CLOCK, 0);
        gpio_output_set(0, BB_CLOCK, BB_CLOCK, 0);
    }
    //
    //  Set the clock and data bits to be low.
    //
    gpio_output_set(0, BB_DATA, BB_DATA, 0);
    gpio_output_set(0, BB_CLOCK, BB_CLOCK, 0);
}

//
//  Timer function called periodically - try communicating with the world.
//
void TimerCallback(void *arg)
{
    struct ip_info info;

    wifi_get_ip_info(STATION_IF, &info);
    if (wifi_station_get_connect_status() != STATION_GOT_IP || info.ip.addr == 0)
    {
        BitBang(0x01);
    }
    else
    {
        BitBang(0x02);
        BitBang(espconn_create(_ptrUDPServer));
        BitBang(0x03);
        BitBang(espconn_sent(_ptrUDPServer, (uint8 *) USER_DATA, (uint16) strlen(USER_DATA)));
        BitBang(0x04);
        BitBang(espconn_delete(_ptrUDPServer));
        BitBang(0x05);
    }
}

//
//  User function which will be added to the task queue.
//
static void ICACHE_FLASH_ATTR UserTask(os_event_t *events)
{
    os_delay_us(10);
}

//
//  Initialise the application and add the user task to the task queue.
//
void ICACHE_FLASH_ATTR user_init()
{
    at_init();
    InitialiseGPIO();
    //
    //  Disarm timer.
    //
    os_timer_disarm(&timerInformation);
    //
    //  Start the network connection.
    //
    const char ssid[32] = "--- Your SSID Here ---";
    const char password[32] = "--- Your Password Here ---";
    struct station_config stationConf;
    
    wifi_set_opmode(STATION_MODE);
    os_memcpy(&stationConf.ssid, ssid, 32);
    os_memcpy(&stationConf.password, password, 32);
    wifi_station_set_config(&stationConf);
    //
    //  Allocate an "espconn" for the UDP connection.
    ///
    _ptrUDPServer = (struct espconn *) os_zalloc(sizeof(struct espconn));
    _ptrUDPServer->type = ESPCONN_UDP;
    _ptrUDPServer->state = ESPCONN_NONE;
    _ptrUDPServer->proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp));
    _ptrUDPServer->proto.udp->local_port = espconn_port();
    _ptrUDPServer->proto.udp->remote_port = 11000;
    os_memcpy(_ptrUDPServer->proto.udp->remote_ip, udpServerIP, 4);
    //
    //  Setup timer to call the timer function.
    //
    os_timer_setfn(&timerInformation, (os_timer_func_t *) TimerCallback, NULL);
    //
    //  Arm the timer:
    //      - timerInformation is the pointer to the OS Timer data structure.
    //      - 1000 is the timer duration in milliseconds.
    //      - 0 fire once and 1 for repeating
    //
    os_timer_arm(&timerInformation, 1000, 1);
    //
    //  Start OS tasks.
    //
    system_os_task(UserTask, USER_TASK_PRIORITY, userTaskQueue, USER_TASK_QUEUE_LENGTH);
}

Compiling and deploying this application to the ESP01 generates regular (1 second intervals) messages on the console application at the start of this post.

Conclusion

The journey with the ESP8266 has just started but it looks promising. The initial set up was not a simple as I would have liked as there are a number of parts all of which need to be brought together in order for the development cycle to start. Once these are all in place then coding is relatively easy even though there is little documentation. The community which is developing is certainly helping in this process.

On the whole this chipset offers an interesting opportunity especially with the like of Adafruit developing the Huzzah DIP friendly ESP12 board which has now received the appropriate certification for commercial WiFi use.