I put together some custom cables with ribbon cable, heat shrink and connector pins to replace the breadboard pins I was using. These connectors are a little more resilient.
I connected everything up including the wireless transceiver and tested the modules both with the I2C scanner and the serial monitor with the initial remote control sketch.
Everthing seems to be working fine so I now need to get the sketch on the main MCU to send data to the Roomba again and then I’ll start work on the case.
The remote won’t work unless it can transmit commands so I soldered up a new Wireless module. Because the Wireless transceiver uses SPI, some pins are shared on the ATTiny84/85 so I decided there would be a direct connection from the ATMega328 to the Wireless transceiver.
I also purchased some AMS1117 3.3v regulators to avoid needing to put a 5v-to-3.3v convertor myself. This reduced the amount of soldering considerably.
I had to solder some extra headers to the board so that the transceiver could be supported. The idea was that I could make the transceiver removable.
This may bite me in the future in terms of size of the case.
Next part to get converted to I2C was the joystick module. This time I needed to use an ATTiny84 because I needed 2 pins for X and Y, 1 pin for the button and 1 pin for the LED plus 2 for I2C which means there are not enough pins available in the ATTiny85.
Soldering was a little easier because there are not so many connections required.
I also cut down the size of the module so that I could build 2 and put one either side of the main remote. This makes it a more compact unit.
The obligatory video below shows it working.
After building the new IO board, I started to realize that my idea to have the remote control in modular sections needed a redesign. Each module needed at least 2 17-pin connectors to provide communication from the previous module to the next and that was taking up valuable space on the small perfboard and that required components to be squashed together ( ultimately exposing my lack of fine soldering skills ).
I was looking at controlling multiple OLED screens and found a technique that used a multiplexer to allow the controller to talk to OLEDs with the same address. The multiplexer switches the I2C data line between each screen.
Using I2C got me thinking about how I could redesign the remote control modules with just 4 pins for the bus ( 2 for power and 2 for data ).
To communicate with each module, I needed a smaller microcontroller that would respond to I2C requests from the main MCU ( the ATmega328 ) and send data back. This meant that I could have the module MCU talk to a shift register to determine button presses or to light LEDs.
I chose the ATTiny85 because it was much smaller and didn’t require a separate oscillator for timing and also didn’t need associated smoothing capacitors for power. However, with fewer pins comes less flexibility. The shift register technique needs 3 pins for control ( data, shift and latch ) but I also needed an input pin for the button module. The ATTiny85 doesn’t have enough pins available to do that. By happenstance, I found that I had a solitary Johnson counter that has 10 pins for output and a one pin for clock. Each time the clock pin is taken high, the output pin is incremented so, for example, if the output pin is pin 1, a clock pulse moves it to pin 2 and so on from 0 to 9. When it reaches 9, it rolls back to 0 again. Additionally, there is a pin to reset the counter back to 0. This is important if you want to poll buttons sequentially. The reset allows you to start from a known state.
So, the module uses 2 pins ( clock and reset ) plus the data input line instead of 3 + input. That makes the Johnson counter perfect for the button input module.
I needed to make sure that the ATTiny85 could talk over the I2C bus to the main MCU.
With that testing done, I could then solder up a new Nerduino and button module. I was also able to test that the ATTiny85 could light an LED module. Given that I don’t care about any input on the LED module, I can go back to using a shift register for that module and still only use 3 pins on the module MCU.
In soldering up the new IO board, I had to make some changes to the joystick panel to make coding for the button presses easier. For each shift register, I have 4 pins for LEDs and 4 pins for buttons. If I press a button, I can now use some simple bit shift logic to light up the corresponding LED. Unfortunately, the joystick panel wasn’t wired up like that so I had to de-solder and then re-solder some connections to fix that.
Also, I had the shift register Output Enable pins pulled permanently to ground which meant that every bit that got written is immediately copied to the output pins. Now that I’m shifting data across 2 shift registers, I could see the LEDs flicker. So, I used up one of the 2 remaining pins on the MCU “bus” to be the Output Enable line for all the shift registers.
Now, when I’m writing data, I make OE high, write all the data and then make OE low to copy the data to the output pins. Problem solved.
Next step is to integrate all these changes into the remote control sketch and then work on the Roombaduino code to act on the new commands.
After giving it some thought, I realized that using the joystick buttons to cycle through the brushes wasn’t optimal and I have some extra space on the remote control in the form of the T-connector piece that connects that MCU, Wireless transceiver and Joystick input.
I have to finish soldering up all the points between the connectors but the key piece is that the pin which is the bit from the shift register as the MSB drops off the end, on the T-connector, should now be connected to the input data pin on the Joystick input. Which means that there are now 2 shift registers to manipulate from the MCU. The first one is on the T-connector and has 4 LEDs and 4 buttons. The second one is on the Joystick input and has 2 LEDs and 2 buttons. I also need to make sure that the pin which indicates a button press is connected across both boards.
I’m also planning to send the status of all the inputs ( joystick position, joystick buttons, 4 input buttons ) as a packet to the Roombaduino.
You may have seen that The Ben Heck Show is also putting together a Roomba project. I’m glad that he went through the same steps I have done and I have a couple more ideas.
Firstly, the Roomba has a command to seek its dock. I’ve built the T-connector IO board so that one of the buttons has a red LED. This will be the one that activates that command. Also, he uses a different set of commands to drive the wheels. I’m going to change the code on the Roombaduino to use the same commands because then I can change how the joysticks operate. I’m planning to control the left and right wheels with their own joysticks so that the Roomba is driven like a tank. It also means that I can send the relative positions of both joysticks and map them to forward and reverse directions. This makes turning while moving forward easier.
The code that I had working on the attiny85 for the OLED didn’t want to work on the ATmega328P even though I made sure that the new pins I’d soldered were fully connected and could light LEDs when sent high.
So, I did some internet searching and found http://blog.oscarliang.net/arduino-oled-display-library/ which does the trick. The Adafruit library seems to be jam-packed with everything and the Arduino IDE complains that there’s a shortage of memory when it’s compiled so any chance to decrease the memory footprint is a good thing. The fact that this OzOled library works is the reason I’m using it. One thing I did notice is that it seems to start the display upside down when compared to the Adafruit and ssd1306 library. I’ll dig into that to see if there’s a simple logic change I can make.
Here’s the obligatory video of the OLED screen working:
With the Roombaduino circuit soldered together, it was time to test the remote control. I found a connection to the left joystick button that had come undone so I re-soldered that. I also move the Roombaduino LED pin and DD connection to different pins on the Nerduino so that I could use the I2C pins for the OLED display at a later time.
With that all done, the software needed some tweaking to allow a joystick button to switch between Passive and Full mode on the Roomba to give me a chance to turn the Roomba off if necessary. Also, the main brush and side brush on the Roomba needed to operate so the other joystick button toggled their movement.
Some improvements to the software, needing some new push buttons on the remote control, will be to allow single-use buttons for each of the functions that are currently being toggled by the joystick buttons. Also, the joystick direction commands should allow the combination of forward + (left or right) and backward + (left or right).
I decided that I needed more visual feedback from the Roombaduino so I can obtain sensor information and display voltage and mode data.
A while ago, I bought a small 128×64 OLED screen from Amazon ( http://www.amazon.com/gp/product/B00O2LLT30) that uses just 4 pins ( 2 for VCC/GND and 2 for I2C [ SDA/SCL ] ). As I’m using the SPI pins for the wireless transceiver and things have been known not to play well with a shared SPI bus, using I2C from the Nerduino seems like a good idea.
After proving that the breadboarded circuit worked as expected, I charged up the Roomba battery and soldered up the Roombaduino circuit.
This time, I was using double-sided perfboard which has its pros and cons ( for me ).
The pros are that the perfboard is better quality than the paper single-sided board and that the pads are less likely to melt and detach when I solder.
The con ( for me ) is that because the pads are double-sided, the solder flows through to the other side. So, if I’m not soldering a component and I want to lay down a power rail, the solder forms in a bump on the other side of where I’m soldering the rail.
I’m sure other people are perfectly happy with it but it doesn’t work for me so I’m going back to single-sided.
I soldered up 3 parts to the circuit.
Firstly, the connection from the Roomba to the circuit through a 5v power regulator. This allows the Nerduino to be powered from the Roomba without needing a separate power input.
Secondly, the 5v to 3.3v power regulator to provide power to the wireless transceiver.
Thirdly, the connection from the Nerduino to the wireless transceiver using the SPI pins.
While the circuit looks compact on the front, I’m still not happy with my wiring ( but I don’t want to take it apart again – maybe in the future ). I need to be more methodical about how I wire stuff to make it more tidy.
What I *am* pleased about is the shield-like design so that the connection to the Nerduino is done through pins and the Roombaduino circuit can stack on top.