Loes Bogers

FabAcademy 2015


Week 13 - Networking & Communications:

making things talk (and listen)

Assignment: design and build a wired &/or wireless network connecting at least two processors -----------

You can make a wired connection, or wireless. Communications and protocols are the same. For wireless you need extra piece of hardware.

------------

Plan for the week

I want to create a master-slave configuration based on the MIC board from the input devices week and the stepper board I did for output devices. The idea is that when you blow into the mic, the motor on the slave is activated, moving a small mechanical bug in a bell glass frame. I can build on this for the final project by producing more slaves (I want three ideally). Because I'm keeping the final designs small and light I guestimate for now that the stepper motors will do if I supply enough power for a strong torque. But I can modify my choice of materials based on this decision without problems.

Components to add to the boards:

Switch board!

I will make a separate switch board to connect an adapter to power all the boards. The adapter is 7V/600mA. One stepper motor pulls 170mA, three motors at the same time will pull 510mA. So everything needs to be a bit bigger and better to support that.

  1. 4x Schottky Diode 1A: one for each board (1x master, 3x slave)
  2. Strong on/off switch - the one I used before takes 5A
  3. 1x 2 pin header to connect adapter to switch board, the 2-pin terminals can take 160V/6A
  4. 4x 2 pin headers to power all the master and 3 slaves, same as the one above
  5. get proper wire! I have wire that can take up to 1A

Figuring everything out...

The Slave(s): motor boards

I will start with getting one slave to work and then at more towards finals. On the motor boards (slaves) I need to have:

    The usual suspects
  1. Attiny44 microcontrollers for slaves I've used in the outputs week for the stepper
  2. 4x N-Channel Mosfet
  3. 2-pin bulky header for powersupply
  4. Unipolar Stepper motor (connected via 4-pin header)
  5. 1uF capacitor between VCC and GND
  6. 10K resistor to VCC on the RST pin
  7. 6-pin header for programming
  8. Extras
  9. an LED (and resistor)
  10. 5V VCC: shared with master)
  11. 7-12V power supply, coming from an adapter that I will repurpose. Output is 7V with 600mA which should be enough. I'll have to split this wire, and add connectors and headers on the boards to get them supplied.
  12. Connections
  13. the slaves will get their 7V, 600mA POWER supply directly from the supply, traces at 32 mil.
  14. the slaves will get share 5V VCC and GND with master, like in Neil's examples. (That way only the master needs a 5V regulator (to transform 7V supply for IC)
  15. and for the I2C protocol they will each also share SDA, SCL, and GND wires with the master via a 4-pin header.
The Master: sensor and control board

The master will control the motors and will have the MIC sensor to do readings on it.

    The usual suspects
  1. Attiny45 microcontroller (44 is not supported for I2C)
  2. 2-pin header for power supply from 7V adapter > 32 mil traces!
  3. 5V regulator to transform 7V supply > 32 mil traces on power!
  4. 1x 4pin header to share SDA, SCL, VCC (5V) and GND with slaves
  5. FTDI header
  6. 1uF capacitor between VCC and GND
  7. 10K resistor to VCC on the RST pin
  8. 6-pin header for programming
  9. 10K resistor from SDA on 4-pin header to VCC
  10. 10K resistor from SCK on 6-pin header to VCC
  11. Potential extras?
  12. A resonator > no space!
  13. skipped this few pins on t451x Microphone sensor (throughole)
  14. skipped this, few pins on t45pamp, resistors and capacitors, see input week
Understanding the layout and usage of pins of the ATTINY - MASTER/BRIDGE in Neil's examples (t45)
  1. pin4 = GND (14 on t44)
  2. pin8 = VCC (1 on t44) route via regulator!
  3. PBO to SDA_MOSI on 4 pin header to slaves , via 10K resistor
  4. PB1 to MISO of 6 pin header to ISP
  5. PB2 to SCL/SCK on 4 pin header to slaves, to SCK of ISP, via 10K resistor
  6. PB3 to TX on FTDI (also put on PA pin when moving TX)
  7. PB4 to RX on FTDI
  8. PB5 = RST (4 on t44) via 10K resistor to VCC
Understanding the layout and usage of pins of the ATTINY - SLAVE/NODE in Neil's examples (t45)
  1. pin8 = VCC (1 on t44)
  2. pin4 = GND (14 on t44)
  3. PB0 = 1K resistor & LED to VCC (pin to cathode, anode to res, res to VCC
  4. PB1 = MISO of ISP header
  5. PB2 = SCK of ISP
  6. PB3 = TX
  7. PB4 = RX > not available on t44, put on PA3
  8. PB5 = RST to ISP, and 10K resistor

  9. When using T44:
  10. pin1 = VCC
  11. pin2/PB0 =
  12. pin3/PB1 =
  13. pin4/PB3 = RST, and 10K resistor to VCC
  14. pin5/PB2 =
  15. pin6/PA7 = 1K resistor & LED to VCC
  16. pin7/PA6 = SDA_MOSI
  17. pin8/PA5 = MISO
  18. pin9/PA4 = SCL_SCK of the ISP
  19. pin10/PA3 = motor1
  20. pin11/PA2 = motor2
  21. pin12/PA1 = motor3
  22. pin13/PA0 = motor4
  23. pin14 = GND

Finding the right components

I had to look carefully at my components, wirings and connectors because I will be pulling a lot of amps with more than one motors. I looked at all the datasheet and calculated the current for these parts of the circuit. Then I found out a bit late the I2C is not supported for ATTiny44. But looking at the documentation of Nabil it looks like it's possible to communicate with t44 slaves if you have a t45 master. I need this because to control a motor I need more pins than the tiny45 can offer. I changed my schematics and layouts again to fix it. For the master board it meant that I had to skip including the Opamp/Mic sensor parts because they wouldn't fit either. That's actually a blessing because it would become a pretty complex board.

I originally wanted to keep a resonator on board rather than to accurate the clock in the code. Zaerc has written some code to do that easily. Let's see how it goes. But because I have to use an ATTiny45 for the master (I2C protocol not supported on 44) I had no choice and not enough pins to do it.

I had to find a footprint for the 2 pin terminals, I found one with 3.5mm dimensions like the one I need in the adafruit library called ADAPTER 1X2-3.5MM package 3.5MMTERM that I think will work. But otherwise this is useful:

How to create your own footprints and symbols in Eagle

  1. Tutorial 1 : Symbols
  2. Tutorial 2: Packages
  3. Tutorial 3: Devices

All looks well, I had to eventually throw some stuff off the boards because of a lack of pins. I'll have to make a separate board for sensor input but that can be done without too many problems and can be added without making an extra board even. I have quite some wires running between boards but we'll deal with elegant solutions for that later.

Producing the board and assembling

It didn't want to mill the cutout because I'd left too little buffer for the size of the milling bit. By telling the modules that the milling bit was smaller than it actually was I could trick it. But next time I should make the margin for the png slightly bigger.

All good, had to look carefully about what goes where.

Programming the board with I2C

Before trying to set up the communication I debugged the board:

  1. Burn bootloaders to 8mHz (even though they have it built in, do it again).
  2. OR: calibrate the clock with Zaerc's arduino calibration sketch that checks all frequency combinations and tells you the best one to calibrate
  3. then I debugged the master by setting up a basic serial communication via FTDI header for ATTiny45 I used this sketch (change pin names!). I always get TX and RX mixed up. But today TX = PB3 (pin2) = pin4 in Arduino. And RX = PB4 (pin3) = pin3 in Arduino.
  4. Double check the orientation of components!

  5. When that worked I checked the Slave (motor board) using the basic blink sketch (there's an LED on the board). This took some debugging, finally I figured out I'd made a mistake in the orientation of the LED. It is reaaaally hard to see the indication of the cathode. And I changed the resistor to 499 instead of 1K to be sure.

Diving into Arduino libs: TinyWireM (t45) and TinyWireS for t44

Refer to Neil's C and code. Or look into Wire library in Arduino: TinyWireM (master) and TinyWireS (for Slave). Big bonus of this protocol is that there are supported libraries that work with Attiny. And it's very efficient in terms of wiring (only two wires to support many slaves).

It's not super easy to set it up. I downloaded the library for the Master45 (default) and the modified Slave44 version via this webpage. But I struggled a bit with importing it and getting the filestructure correctly to access the right lib for each. This is what it should look like.

then I cobbled together sketches from the arduino examples and started testing it out. I just want to give input via the serial monitor and have the master transmit to slave who responds by blinking the LED.

The first attempt I got the master sketch to do everything it's supposed to: it responds to serial monitor input saying "Online", "Starting Transmission", "Ending Transmission". So far so good, but no response from the slave yet. The slave sketch is obeying what I tell it in the setup: blink the LED twice to show you're alive. But then nothing. But actually all this serial stuff was just to confirm initializing a serial communication. So I simplified the sketch to just send a byte to the slave (1 in decimals = 0x01 in bytes). But before I even got around to it my master sketch started giving errors in compiling before I even changed anything! WHYYY?! It looks like it can't find the library files properly anymore. So I installed, reinstalled and reinstalled it a bit more. But no luck.... But before I even got around to it my master sketch started giving errors in compiling before I even changed anything! WHYYY?! It looks like it can't find the library files properly anymore. So I installed, reinstalled and reinstalled it a bit more. But no luck.... SOLUTION: it won't compile unless you have the right board selected in the IDE! Even if you're not uploading yet, you need to have the right board selected.

Then I got so far as getting the light on by sending 0x01 (decimal 1) to the slave. But it seemed a bit arbitrary. I calibrated the clock using this code by Zaerc. The best values were beteen 0x53 and 0x62. When you open programmer mode in calculator to add these up and divide by two you get 0x5A. In the setup you put this:
OSCCAL= 0x5A; // is calibrated clock value using tinyOscalTempt45
delay(1);


What I ended up with was this working code. But it gives very irregular on and off signals....

This is what that looks like. We checked with a program called Logic to see what signals are being sent up and down. It basically visualizes exactly what bits are being sent to and fro. Quite nice. But it didn't tell us much new except that it's weird. It looks like it's giving the same commands all the time where it should be alternating on/off. Thats also what the LED is doing so double weird.

I understand working with the libraries and the debugging but I would have to do more serious debugging to figure out why the communication is behaving strangely.

Further debugging and lessons learned

We went back into the boards and checked board by board that the were getting the right voltage, on the ICs and the right voltage on the higher power lines of 7-9V. We'd established that the adapter was broken, it worked earlier but when I plugged it to the boards, afterwards it wasn't working anymore which was a concern. We used the power supply in the lab. All the boards and the regulator on the master were working fine. But as soon as we mounted the stepper to the slave board it started pulling a lot of current. Something there needs to be looked at.

I debugged the boards by adding a bigger GND line from the switch board to the slave with the motor. (Before it was just going via the SDA/SCL/VCC/GND ribbon wire. But because a motor pulls a lot of current it would be better to have a big GND line so I added a jumper. And the regulator was busted so I replaced it.

Lessons in code

I learned that keeping the FTDI communication and the I2C communication in different voids in the code. Eg. don't put a serialprintln command in an if statement using the I2C protocol.

Apparently you can send values between 0-255. Other values are not sendable. If you want to send values like a number, or a character. Use "char" variables in the code. Otherwise Bytes in hexadecimal values (eg 0x52), bytes are better.

Emma suggested I'd consider writing my own protocol to really control what is happening in the communication. The arduino library is nice enough but you don't have full control. If you know what it needs to do, might be worth writing something else. Simple boolean logic using two lines can already do 4 tasks. In another case. My classmate Frank Vloet managed to get I2C rolling between two ATTiny44s using C code that he collected and cobbled together. Pretty impressive hey Frank! I could draw from his research perhaps.

This note about the TinyM lib for attiny85 says it's default at 1mHz clock speed. I'm using 8mHz on the master! check here. Maybe this is the timing problem....so I changed the command #define SYS_CLK 8000.0 // [kHz] in the USI_TWI_Master.h file, and the command #define F_CPU 8000000UL in the USI_TWI_Master.cpp file. I removed and re-included the libraries. I re-burned the bootloaders on the ATTinys, and uploaded the code but unfortunately, the signal is still irregular.

Simplifying code

I went back to a realllllly simple sketch to check and monitor the communication using the same code Till used this week:

  1. Master code
  2. Slave code

It simply sets up communication between master and slave, and the slave gives alternating high or low values back to the master. The master prints it to serial. What comes out are a lot of 255s in a row, then a lot of 0s in a row. Instead of alternating 255, 0, 255, 0 etcetera. So even with simple code the problem remains.

I went on to play with I2C a little bit in the interface application programming week: I wanted to know how to interface a Microview (Arduino with built-in OLED display) with another controller. Using the Arduino toolchain however (shame on me!.. NOT. This was for fun and practice :)

Workfiles

CODE

  1. Master
  2. Master with serial input
  3. Slave
  4. tinyOscalTempt45 by Zaerc
  5. Basic serial test

And the board layouts and schematics

    MASTER SLAVE SWITCHBOARD

Resources: Nabil's servo driver board from last year

This is the Wire Library for Arduino. And here's documentation on how to use this library to encode the Master writer/Slave Receiver and the Master Reader/Slave Sender.

------------

Note about Neil's boards

  1. resonator
  2. they all share VCC and GND but this is optional, you can change it depending on the application
  3. Neil's bridge (main board) has FTDI header because his code requires it. But you don't need it to communicate between the boards.
-----------

Local class on Networks & Communication

What does that mean, a protocol? For example....

HS-323 standard

Uses signals between 0 and 13V. If there is no data, the signal is low (this is not the same for all standard.

TTL

Is the opposite: the signal is high when there's no data and it's between 0 and 5V

------------

Asynchronous serial

Asynchronous because you don't use an external clock, you're just sending data. RX to receive, TX to send and a GND if you want to share the boards' GNDS (Neil's board share VCC and GND. Direction is always TX > RX.

No clock? Means you need other rules to communicate, protocols. Eg number of bits. The signals we're sending are digital, HIGH or LOW, 0V or 3.3/5V. Note: the boards don't share a clock, but it's wise to give them each their own clock (the same type).

  1. Baudrate: all boards need the same rate. Measured in Bits Per/Second (BPS). A bit is a phase. How fast it is sent. Standards are: 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200. For example: 9600 bps > 1/9600 is one bit every 104 microsecond.
  2. Hardware: UART. Attiny doesn not have this implemented. Then you do it in software, using a library eg. SoftwareSerial. Then the serial interface can be bit-banged - directly controlled by the processor.
  3. Reference: Neil's board and codes. There's no example of someone using the Arduino lib for this assignment. Use Neil's C code to program it. Or try to use the arduino lib.
  4. The code that you use is the same for the two nodes, but you have to change the names. Each node has to have a name to identify and call it.
  5. You can share the GND and VCC with the 4 pin serial (VCC, GND, TX and RX in Neil's boards). If you share them you only need one power supply. If you need heavier supply like with motors; think about the application: you can share the 9V supply between the boards and give each a 5V regulator. Or share the 5V from the first board to the others.
  6. Downside of this is that communication can be unstable and fail because there's no shared clock. But it doesn't require a lot of wires. SPI or I2C could be a good alternative.
----------------------

SPI - Serial Peripheral Interface

It's a synchronous data bus, with a clock! Means it uses separate lines for data and clock. To keep it synchronized. Requires 4 wires: SCK = clock,

  1. SCK = clock
  2. MISO = Master In Slave Out - is TX. All boards share MOSI's (not like TX > RX)
  3. MOSI = Master Out Slave In - is like RX. ALl boards share MISO's
  4. SS = Slave select. Way to address the right node/slave. You need one wire for each slave (slave is a node). So this requires more wires

You have a master and a slave. Master distributes clock signal. Main board is managing communication, then it's ok. If you need two way communication you will need a lot of wires.

Programming SPI communication

There's an SPI library, but it's not developed for Attiny. You can use the shiftIn() and shiftOut() commands in the Arduino IDE. There's an example of someone who used Attiny85 for this assignment with this method. There's no example from Neil. Benefit from this method: more stable and accurate timing between boards because they share the clock. Minus: requires more wires.

------------------------

I2C Communication (also called TWI: Two-Wire serial Interface)

Just two wires can support up to 1008 slaves. This is a very strong protocol. You need 2 wires: clock (SCL) and data signal (SDA). You send a minimum of two frames: 1) identify the slave (always), and 2) data to tell the slave (or more frames to do different things on this address. Packet > Frames > Bits.

Outline of the protocol
Frame 1: address packet
  1. Start communication: master sets clock HIGH and data signal LOW.
  2. Address of slave : 7 bits
  3. R/W : gives information of what Master wants from slave (read it or write to it)
  4. ACK : is like a check, to see if slave is ready to respond (optional)
Frame 2: 8 bits of data + ACK
  1. 8 bits of data
  2. ACK : check if slave is responding correctly
  3. signal to end communication: SCL (clock) is set to HIGH, stays high, SDA (data signal) goes HIGH
Programming I2C

Refer to Neil's C and code. Or look into Wire library in Arduino: TinyWireM (master) and TinyWireS (for Slave). Big bonus of this protocol is that there are supported libraries that work with Attiny. And it's very efficient in terms of wiring (only two wires to support many slaves).

Check the devices you use, if they support I2C the process can be relatively easy. It's a well-used standard.

Resource: Nabil's servo driver board from last year and how he used the module for the communications week as well. -----------------------

Wireless Modules

Look up documentation of other's and their examples. Most of the have a clock integrated, and already implemented protocols incl libraries to use in your code. Takes away some of the hard work.

Creative Commons License
Fabacademy2015 work by Loes Bogers is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.