Sunday, 7 September 2014

Loading an array/slice of objects from a JSON file in Golang

As usual, with a new project arriving my first question is "what can we learn on this one?"

So, having found that Go (aka Golang) is a decendant of Modula-2 and has some pretty nifty features, I decided that Golang was the way to Go (if you will pardon the expression).

The next thing that I do is head straight for the target, reading just enough to get me there. If the journey is a happy one I may flesh things out later, but when you are relying on the internet and googling, the search results are a bit like flicking through a book - but not as good because sometimes a book yields a gem that you weren't looking for.

The project is made of multiple servers (raspberry pi) doing crazy stuff all talking to each other as well as hardware and Arduinos. The first server was a sound player controlled by other remote servers. It loaded a name->filename map from a JSON file. Not too tricky.

The second one needed some routing tables loaded. I wanted pure object arrays loaded from JSON.

Note : You can't use an Array, you need a SLICE. Arrays are fixed size.

I Googled and came across lots of people on StackOverflow asking the same question.

A lot of the answers and questions revolved around interface{} which I tried and got working but it seemed a bit tricky because there are multiple type conversions involved - silly when all records are the same type. And there seemed to be NOBODY telling how to do it.

So, if you are trying to load an array slice of objects from a JSON file - bearing in mind I have been doing this for a couple of weeks with a lot of that time goofing off, here it is....

The data record I want to load

type command_record struct {
Source    string
What      string
Condition string
Value     string
Host      string
Action    string
}

Which we will represent in JSON as

[
    {
"Source": "sensor",
"What": "temp",
"Condition": "GT",
"Value": "35",
"Host": "sensor",
"Action": "REDON"
    },
    {
"Source": "host",
"What": "sensoralarm",
"Condition": "NIL",
"Value": "0",
"Host": "sensor",
"Action": "BLUOFF"
    }

 ]

So the slice is represented as 

var sensor_script *[]command_record

Note the * which means we are only declaring a pointer.

And we read the file into a slice of bytes

file, e := ioutil.ReadFile("./sensor.json")
if e != nil {
fmt.Printf("File error %v\n", e)
os.Exit(1)
}

Then we convert it objects using json.Unmarshal and print it just to show it works

json.Unmarshal(file, &sensor_script)
for _, v := range *sensor_script {
fmt.Println(v.Source)
fmt.Println(v.What)
fmt.Println(v.Condition)
fmt.Println(v.Value)
fmt.Println(v.Host)
fmt.Println(v.Action)
fmt.Println("=========")
}

And, after all that time - it is that simple. And I am sure that many many people have figured it out within ten minutes, but others have too google it and waste a lot of time. This is for them.

 The code and a sample JSON file can be found on Github at https://github.com/DaveAppleton/LoadObjectSliceFromJson

Monday, 5 May 2014

Build a simple Transistor Curve Tracer using an Arduino and Processing

You always get to that point, when teaching something easy, that you start to cross over into the realm of the slightly more complicated. That was what happened when I started showing how to use a transistor to buffer an Arduino output to switch a 12V load. So we started going into current amplifiers, Vbe and Vce, Saturation and configurations.


The next day, on my way to a meeting I was struck with the idea that an Arduino could make it really easy to show how a transistor works – and it would be more understandable because the students would build it themselves.

The theory


A transistor is a current controlled device. It will control the current through the collector to be a multiple of the base current as long as that current is available.The last part is important. If you have a supply that can only provide 10 mA, there is no way that the transistor can manufacture more. It can only allow the current available to pass or restrict it.


Ic = max (β x Ib ,,available)
where Ic is the collector current, β is the gain and Ib is the current into the base.

In common emitter mode, the load and the supply voltage determine the maximum available current. So, for example, a 100 ohm load to a 5V supply cannot possibly supply more than 10 mA to ground by virtue of ohms law.

The Implementation


The idea was to start off with something incredibly simple that the students could understand – so I settled on manual control of the input voltage using a potentiometer.
The transistor and the two resistors form part of the test circuit.

Test Circuit Diagram


Thus the Arduino is able to measure the source voltage, the base voltage and the collector voltage as you change the potentiometer position.

Thus Ib can be determined by ( Vs – Vb ) / Rb
and Ic can be determined by (5V - Vc) / Rc
This was easily wired up on a breadboard as follows


The Arduino code


Since we want to graph the output, we will send it to a host computer via the USB Serial link. This reduces the requirements of the Arduino code to reading the analog inputs, converting them to voltages and transmitting them.

Since the Arduino has 12 bit analog inputs (0-1023) where 0 represents 0V and 1023 represents 5V we need to scale the analog readings.

V = analogRead( port ) * 5 / 1023

We then combine the three readings into a single text line and transmit them in text mode to the computer. Using plain text makes it far easier to debug the program on both sides. As a result, the Arduino code is really simple.

                                       
void setup() {                         
  Serial.begin(9600);                  
}                                      
                                       
void loop() {                          
  float bvc  = analogRead(A0);         
  float bvb = analogRead(A2);          
  float bvs = analogRead(A3);          
  // convert to volts                  
  float vc = 5.0*bvc/1024.0;           
  float vb = 5.0*bvb/1024.0;           
  float vs = 5.0*bvs/1024.0;           
  // transfer in one single line       
  Serial.print(vc);                    
  Serial.print(",");                   
  Serial.print(vb);                    
  Serial.print(",");                   
  Serial.println(vs);                  
  delay(500);                          
}                                      
                                       


And that's it! The program simply reads the voltages and sends them to your computer which has the job of interpreting and displaying the data!

We use the computer to receive and display the data so we write a small program in processing that will read the data from the serial port and store it into a list structure. A serial event is generated every time a new line of text arrives. The data is extracted and put into an object which is stored in an ArrayList. The ArrayList is sorted based on Ib as each item is added because data can come in out of order as you twiddle the potentiometer knob. If you turn too fast you will start with a very rough graph. You can refine it by turning it backwards and forwards – or turning it slowly.

The program then draws a graph background and plots the required graph as selected by the user.

The program then draws a graph background and plots the required graph as selected by the user.

Options available:

  • Ib / Ic - press C
  • Ib / Vc - press V
  • Vs / Vc - press B

Additionally P clears the graph and Q will close the connection to the Arduino

Since the Processing code is somewhat more involved, you can download it from GitHub from the link at the end of this article. The raw data gives us the following curve:


Collector Voltage vs Input Voltage

This is a plot of the raw data from the Arduino - but is really only useful for understanding exactly this configuration (with these exact resistors). However it does show you that you have an inverting amplifier.

 Calculating using the values of the two resistors allows us to determine the current and get Ib / Vc and Ib / Ic plots

Variation of Vc with Ib


Variation of Ic with Ib


Results


The Ib/Ic curve shows the tail off of the gain when the transistor reaches saturation. The saturation occurs not because of the transistor but because the resistor cannot allow a current of more 5v/Rc to pass given the 5V supply.


As you play with the potentiometer, you will notice that more points make the curve smoother. Depending on the consistency of your connections you may experience a few glitches but you get enough data to see the pattern.

One reason you may get some glitches is that you may be moving the potentiometer too fast, thereby causing some inconsistency in the potentiometer value between the three readings.

Improvements


The circuit seems to work pretty well – and the curves are OK except that they are a bit jagged.
On refelection, we are assuming that all three readings are under simultaneous conditions when in fact, moving the potentiometer means that the readings are not at the same point. Just as important, we cannot cover a smooth range of input voltages (Vs) because we are manually turning a knob on the potentiometer.

The obvious first improvement would be to replace the potentiometer with something similar but controllable by the Arduino. Two contenders would be either a Digital to Analog convertor or a Digital Potentiometer. In this design I settled for a Digital Potentiometer for the scientifically precise reason that Element14 had some in stock so they arrived before the DAC chips. Hence I settled on the MCP4131 Single Channel 7 bit Digital Potentiometer.

The MCP4131 is an SPI device with a small difference. I will be covering the nuts and bolts of SPI in another post. This device shares SDI and SDO so you need to add a small change from the usual circuit - which is a single resistor as shown by this note in the data sheet.


The calculations required by Note 2 are that
  1. When the first edge is asserted, the resistor must be low enough to allow the CPU to drive the device's pins both high and low
  2. When the second edge is asserted, the resistor must be high enough to allow the device to override the CPU's outputs.

The calculations require reading both the CPU and device's data sheets but show that in practice there are quite a wide range of values possible. I selected a 4.7K resistance out of sheer instinct. 

This is really simple to implement as shown below.





And the wiring is just as easy


Revised wiring using MCP4131 digital Potentiometer

To use the MCP4131 you can download and install the MCP4131 library. I thought I was going to have to write it - but it is quite a simple library.

https://github.com/johnnyonthespot/MapleLibraries/tree/master/MCP4131

One important thing to note is that although it is a seven bit device, the vales range from 0 to 128, not 127 as you would normally imagine.

 Use of the MCP4131




#include <SPI.h>
#include <MCP4131.h>

//setup an instance of MCP4131
MCP4131 MCP4131(10); // with a CS pin of 10

In the setup code

MCP4131.setTap(MCP4131_MIN); //Sets the pot to 0.
if (MCP4131.initTCON()) //init the pot, connect wiper0, and turn ON pot
{
    Serial.println("Init Error!");
}


And in the loop (with a variable “tapValue” which is suitably declared and controlled somewhere)

if (MCP4131.setTap(tapValue))
{
   Serial.println("setTap Error!");
}


And that's it. 

Since I had to write changes to the Arduino code to use the MCP4131, I also modified it to do a single sweep of the Potentiometer (with tapValue from 0 to 128) and then stop until it received a “G” on the serial port.

Then I modified the Processing code to send the G when the user requested for a new graph to be drawn.

The result was far smoother graphs.



That's is about it. There is a ton of future work to be done - starting with different transistor configurations.


See the GitHub repositories below for code:







Monday, 29 April 2013

Geekcamp SG




Last year, in a fit of wild enthusiasm I offered to talk at Geekcamp SG. The talk was to be called "Hardware is NOT boring" and would show racing cars being controlled by a mobile phone and an Arduino. Sometimes this is the only way that I can kick myself into doing something for fun.

The thing is, you only get to talk if enough masochists vote for you. They did.

With the deadline looming, I stayed up late in my favorite JB coffee shops working on the code, built hardware by day - and worked out a backup plan (trains) in case the cars didn't want to run properly.



I had to be in North Johor the day before the event till late - when all was done I jumped on the Harley and rode like the devil down Highway 1 to Singapore. Gotta love night rides on un-illuminated Malaysian roads. Reached Singapore at 4, stayed up till about 6.30, grabbed a couple of hours sleep and made it to GeekCamp just in time.

Being a bit dazed, I was not really awake enough to pay attention to Subh's talk so I started hacking a mouse controlled by a 3D accelerometer and an Arduino Leonardo - which also made it into the talk. Went home, out like a light - but up early next day for Hari Raya.

So seriously, am I stupid enough to do it again? Not a chance. This year I have a partner in crime : Adnan Jalaludin, the designer, maker and seller of the Raspy Juice - an add on board for the PI which features a buck regulator, real time clock and an AtMEGA processor for servo control.



So, this year it is all about Raspberry Pi, Servos, DC motors, webcams and anything else we can get our hands on. We will be drawing on Adnan's encyclopedic knowledge of Linux, Hardware and other stuff and seeing what we come up with.

I, for one, am quite looking forward to seeing it.

And there will be circuits you can build.
There will be software to download and try.
There may be flying things if I can bend enough ARMs....

Oh yeah. When things don't work, there will also be some really bad jokes.

Geekcamp SG.
7th September 2013,
Microsoft Singapore.

Monday, 21 January 2013

Thursday 31st Arduino Intermediate class - coming?

Since Curica seems to be down - and I am not keen to use any of the sites that want you to pre-pay - may discourage you from committing (in case you need o drop out) / coming at the last minute, and I don't want to side step their payment mechanisms - I am resorting to asking you to simply drop a comment here to indicate if you are coming.

Details: 

This session we will cover

1. Use of Serial port for 
       Output
       Debugging
       Input (interaction)
2. Interrupts
3. Timers
4. Seven Segment LED
5. Servo Motors

Venue: Hackerspace SG, 70 A Bussorah St, Singapore 199483

Date / Time: Thursday 31st Jan, 7.00 p.m. - 9.00 p.m.

Cost: $45.00 if you have change - otherwise $50.00

Basic class - Friday 25th Jan - Coming?

Since Curica seems to be down, I am not terribly keen to use any of the online booking systems that make you pay in advance because I understand that things come up at the last minute and so you may not be able to make it - and likewise you may want to come along at the last minute....

So - if you are coming - please leave a comment here

Details:

By popular demand we are yet again offering yet another reprise of our introductory hands on course that will teach you how to build cool things with the Arduino - the open source micro controller platform that has changed the world by making micro controllers accessible to hobbyists at a really affordable price. You will learn how to use the Arduino in your hobby projects. Control LEDs, Buzzers etc, detect the state of buttons & sensors. Some simple programming and electronics will be taught (emphasis on simple) but you will get results very quickly. Hackerspace are making their Arduino kits available for the class so all you need to do is to bring along your notebook. Beginners class. (repeated by popular demand) You will need to bring your own laptop.

Venue:   Hackerspace SG, 70A Bussorah St, singapore 199483

Date / Time: Friday 25th Jan, 7.00 p.m. - 10.00 p.m.

Cost: S$ 45 if you have change, otherwise $50 ;-)


Tuesday, 15 January 2013

2013 - Happy New Year -
(Taking "arang batu" to Istana Bahru)

IOBLOCKS is starting 2013 from Istana Bahru - a new home in Johor Bahru right next to one of the Sultan's palaces. The place is quite a mess having combined the old office with heaps of personal possessions.

We have been here since October 2012 but the insanity of teaching schedules of my Image Processing classes at DigiPen meant that those few remaining free minutes were used looking after clients rather than creating some kind of order.

Our Android Apps for Cytech Technologies' Comfort home control system are now available on Google Play. They have been pretty well received. Now it is time for the iPad version.

January 2013 will see two Arduino classes at Hackerspace SG - a basic class on the 25th (Friday) and an intermediate on the 31st (Thursday).

The Intermediate session will feature Serial ports, debugging, 7 segment LED, Servos, interrupts and timers.

Finally - received an excellent testimonial from a client even though we didn't get the job...
"In the short time that I spent with you, it impressed upon me that you had machine vision knowledge that was far better than the other vendors. I'm lining-up a few more Vision Inspection projects and will be contacting you soon."

Monday, 24 December 2012

Keypad code available on BitBucket

You can now download the code for the Keypad/LCD code from BitBucket

This is my first attempt using BitBucket so please let me know if there are any problems