I thought it was about time I put my display driving code on the FPGA to good use So I added the X, Y and Z values to the power value already transmitted from the Arduino, and got the display up and working.
A minor annoyance was the Arduino IDE crashed at one point in a way that was completely unkillable (even kill -9), so I had to reboot my Mac. Also, my Merc seems to be ill so I’ve moved the accelerometer over to the Porsche with the new engine – which seems to be running very smoothly now.
The end result is here:
The dot moves up/down for acceleration/deceleration and side to side as the car goes round corners. Or it’s meant to – as you can see, it is certainly skipping about, but you need a reasonable amount of imagination to believe it is related in any way to the cars movement… This could be harder than I first thought!
I think the next step will be to try and improve the data rate from the car – currently I can only hope to get back 10 readings/sec.
As ever, I’ve updated the Arduino and FPGA repos with the latest code.
Now I have a reasonable RF link, I’ve been trying to get the car to drive around the track.
I have a slightly odd setup for controlling the power to the track. Because I made this up before my Arduino arrived, I’ve got a Xilinx FPGA on a Basys-2 board setup to control the track. This board is quite handy because it has 8 on-off switches and 8 LEDs (and a variety of other things) on it.
Up until now, I’ve controlled the voltage with the switches. The design loaded on the FPGA is very straightforward, I’ve got an 12-bit counter counting up at the clock frequency (50MHz), and when the top 8 bits are greater than the value set on the switches, power is applied to the track through a Darlington pair of transistors.
I added a simple serial channel from the Arduino to the FPGA so it could set the voltage. This was a very straightforward design: 2 wires, a clock and a data line both driven from the Arduino. Data is sent 1 byte at a time, simply by sending 1 pulse on the clock line, and then 1 bit of data each subsequent time the clock rises. To make this slightly complicated, the Arduino outputs are at 5V, and the FPGA’s maximum allowed rating on an input pin is 4.4V. So I’ve got a simple voltage divider to get the inputs down to 2.5V.
Initially, this didn’t quite work – it appears that at the 50MHz frequency of the FPGA the signal was bouncing – I fixed that by ignoring changes in the clock line until it was stable for 16 cycles (I suspect less would have worked, but it doesn’t need to be *that* fast).
I have the value sent from the Arduino displayed on the LEDs on the FPGA so I can see what is going on. The top switch on the FPGA now selects whether the value from the Arduino or the value set on the rest of the switches controls the power to the track.
My first proof of concept was to simply increase power to the track until the accelerometer detected any movement, and back off until the movement went away, then increase again. This successfully made the motor hum without the car moving (perceptably).
I now have it set up to increase the power while the accelerometer readings are close to their average values, drop the power if they start deviating a bit, and cut the power significantly if they go over a certain value. This allows the car to go round the track in fits and starts, but without flying off.
Finally, mchr3k has taken my Manchester library changes and is now hosting the definitive version here. I’m including that as a submodule in my Arduino repo. I’ve also made a new repo for the FPGA design.
As mentioned previously, I’m now using a Manchester encoding library linked to from mchr3k‘s blog, and originally posted here, to transmit data from the car back to my Arduino Uno.
I took a bunch of changes from mchr3k, including comments and sorting out the code layout and fixing a couple of bugs. This now gives a very reliable connection between the car and the receiver – I’m seeing errors well below 1%.
I also wanted to be able to transmit a variable number of bytes (the original code always transmitted just one 16-bit integer) and have now got that coded up and working.
The full code with comments is available on github. See the code for a good description of how it all works – it is now commented fairly well. I hope that this will be a useful resource for other people trying to use RF modules with the ATTiny.
In the medium term I’m hoping to improve the library further to deal with interference better – right now the code just gives up if a transition occurs at an invalid time. I hope that if I do that I’ll be able to turn the bit rate up a bit.
It would also be nice to produce an interrupt driven receive side, to allow the receiver to avoid having to sit in the receive loop all the time. That’s not my priority right now though.
I never got round to trying out my new motors yesterday, so I thought I’d give that a go this morning. I replaced the motor in one of our two old Porsches.
Unfortunately I broke the motor mount slightly when getting the old one out – the old plastic couldn’t take the flex (or maybe I’m doing something wrong, I did seem to have to push very hard!) Still, the motor seems be in held in well enough to run round with no problems.
The tyres on the Porsche are knackered so it slips all over the place, which makes it rather a challenge to drive. Unlike the Merc, I couldn’t get it to go round just with a steady voltage. Hooking up the controller, I had a race between the computer driven (i.e. steady voltage) Merc and me driving the Porsche – the computer won, but I think I did reasonably well considering the lack of grip.
If I can fix up the other Merc then we should be able to have a fairer race. I’ll get you next time, Gadget!
Back from Maplin, I was eager to try out running the accelerometer on the car.
The circuit has now got a little complicated. I was hoping to draw it out but that will take longer than it took to wire up, so you’ll have to do with a description.
I need two voltages – the 9v battery powers the transmitter, and I use a 1k resistor and 3.3v Zener diode to generate 3.3 volts for the accelerometer and ATTiny.
The output from the Tiny now has to be amplified back up to 9v for the transmitter. I had a TS358 Op Amp around that I’m using to achieve that. The positive input to the Op Amp is connected to the output from the Tiny, and the negative input to a voltage divider of two 100k resistors, between 3.3v and ground. The result of that is the negative input is held at around 1.6v, so when the Tiny drives the positive input low, the output goes low, and when the Tiny drives the positive input high (3.3v) the output goes high (9v). The output from that then goes to the transmitter.
The result looks like this:
The problems I have now are that transmitting the readings back takes too long – a corner only lasts a few transmits – and I’m still seeing odd bit errors despite the checksum. I hear that there might be a bug in the Manchester library though, so that could explain that.
Plans going forward (not necessarily in order) are to:
Speed up the transmission (the library is only writing data at 500bps, I think we can do better than that)
Look into error correction with a Hamming code
Transmit only the useful range of the accelerometer output, and only at useful resolution
Get the readings to my FPGA so I can visualize the G force (I already have that driving a 1024×768 display)
Think about how I’m actually going to control this in software!
The RF link is slow, and unreliable, so given that I came up the following scheme for transmitting the readings back:
Only transmit readings when they change
Transmit each reading 3 times when it changes
Add a checksum so the receiver can tell if the reading was transmitted OK
The Manchester library I’m using (originally from here) just transmits 16-bit integers, so I want to pack everything into 16 bits.
The reading you get out the ADC on the ATTiny is 10-bits, and for now I’m transmitting the whole of it. The next 2 bits identify the axis the reading is for, and the final 4 bits are a simple checksum (XOR of each of the groups of 4 bits together).
The receiver checks the checksum, discards the reading if it’s wrong, and otherwise updates the axis and sends the reading out to serial (for now) so I can see what it’s up to.
I’ve been worried that the watch battery solution wouldn’t work well – the voltage you can expect from a battery is barely enough for the RF transmitter.
So I’ve decided to try this with a 9V battery instead. They are fairly light, and as the pictures below show, my car can carry them round the track ok (and crash and spill the breadboard and battery on the floor – oops, maybe I need a better solution for holding them than blu-tac – nah, just more blu-tac ).
Also, that means I don’t have to go to Maplin today! One thing I do have to do though is go pick up the new Scalextric motors I got from ebay (all but one of the rather ancient cars have dead motors).
Next up though, sorting out that accelerometer data transmission.
The manchester encoding library from mchr3k worked great, and I quickly made a reliable connection between the Tiny and the Uno.
I was worried about RF interference from running the Scalextric car, so I left the transmitter by the track and ran the car round. That seemed to make no noticeable difference to the signal quality, so I’m happy that I’ll be able to get data back, and at a pretty reasonable data rate.
Next up was adding a header to the Accelerometer board and giving it a go. The setup for the accelerometer is very simple, 1.8 – 3.6V in and analog outputs for the X Y Z readings. I got the Uno hooked up and used the inbuilt ADC to read the pins – and it worked first time.
Finally, I wanted to get it going with the Tiny. Only minor problem here is that I’m powering the Tiny with a 4.5V battery pack. I’m planning to get this working from coin batteries eventually, but I haven’t bought them or the clips yet. So I just used a simple voltage divider (two 5.1K resistors I had about) to give a sensible voltage for the accelerometer for testing.
With that all wired up, I could transmit the three readings using the ADC on the Tiny to the Uno! Only problem I have at the moment is the Uno can’t tell which reading is which, so if a single reading is lost the axes all rotate one place I’ll post the code once I’ve added some markers to fix that up.
The idea is to mount the accelerometer on the Scalextric car, and use the ATTiny and the RF transmitter to get the readings back to the Uno or my FPGA (or maybe RaspberryPi when they are finally released). I’ve already got logic and a circuit which allows me to control the power to the car from the FPGA (using a PWM signal).
As a start, I’ve been trying to get a reliable signal from the Tiny to the Uno. Unfortunately libraries such as VirtualWire don’t work on the Tiny, so I tried going back to basics. By the end of last night I’d written something to just bang bits out at 2400bps with a preamble but no checksum. That worked some of the time, but wasn’t very reliable at all (even with both on the same coffee table).
Luckily, a friend is working on a similar sort of project, and he’s got a Manchester encoding library working on the ATTiny85, with a reasonable amount of success. So I’m going to steal use that and see if it improves things.