MartinRisseeuw how to make almost anything

Networking

Task:
design and build a wired &/or wireless network connecting at least two nodes

Description:
For my final project I would like to make the lamp standalone, for this a colleague of my told me that I could try the nRF24L01(+) 2.4GHz Wireless Transceiver. Through this communication I want to give a colour input to the lamp representing a certain need of the user (concept to be found here).

What did I do:

  • Research the nRF24L01(+) 2.4GHz Wireless Transceiver
  • Design two circuit boards
  • Milled out boards
  • Trying to program the board

nRF24L01(+) 2.4GHz Wireless Transceiver:
The transceiver is a pretty cheap solution for a network. The transceiver runs under a 1.9 to 3.6V supply range, which means that it works well on a coin cell, this was necessary for the standalone lamp. For the board connected to the computer I needed a 3.3v regulator. The transceiver has 6 connection pins but you can do it without the interrupt request (IRQ). I decided to use it because the attiny44 has an IRQ and I had enough pins for the other functions I needed. I checked out the mirf library for the ATTINY84 to connect the pins on the right pins.

Design two circuit boards:
After checking all the connections and if I had the right amount of pins I started designing the board. I needed one board that would transmit my code to the receiver.

For the transmitter I used this components:

  • ATTINY44
  • 6 pin header
  • 2x 4 header (cut from a 2x 5 header)
  • programming header
  • 3.3v Regulator
  • 3x 0.1uF capacitor
  • 0Ω resistor(jumper)
  • 10K resistor (pull-up)


For the receiver I used this components:
  • ATTINY44
  • Coin cell holder
  • 2x 4 header (cut from a 2x 5 header)
  • programming header
  • 3.3v Regulator
  • 3x 0.1uF capacitor
  • 0Ω resistor(jumper)
  • 10K resistor (pull-up)
  • RGB LED
  • 3x 500Ω resistors
  • I copied my other design but I forgot to take the 3.3v regulator off. I don't need the regulator anymore, because the board will use a coin cell battery. My solution a solder jumper.

I had some problems with my design in Eagle, some of the labels weren't connected well and I found out after milling and soldering the board. I redesigned my board for next time but my dirty solution for now; Wires.

Milled out boards:
The milling went not well in the first try, this because of the machine's setup. Eagle cut a little bit of my border so it did not cut out my board well. I used Photoshop to edit the image so it would be more clear for the machine.

Trying to program the board:
For the programming I used the Arduino IDE I installed the suited ATTINY core to be sure it all would work. Then installed the libraries to my Ardiuno IDE that I found here. In this package there are also a couple of example sketches that I want to try out.

After installing all the right libraries it was time to program the board. I connected my transmitter board to my FabTinyStar and tried building the software. I got back some errors that some of the pins were not declared well. This was because in the SPI85.cpp the ATTINY44 was not declared. I changed this in the code and tried building again. It worked.

Now it was time to upload the example code to the board but unfortunately I got an error that the "Binary sketch size: 5,024 bytes (of a 4,096 byte maximum)" was too big. So I was stuck because it was already the minimum code needed for the project. I tried leaving out the debug code and it was able to write but the debug code is an important part to see if the board works. So I decided to order two ATTINY84s to replace the ATTINY44 with (I want to do this today). I forgot to make the fuses whic are very important! I did this through the Arduino IDE after installing the core packages. You can select the board and then burn the boot-loader on the board.

Assignment images:

3D print settings
image.1 The nRF24L01(+) 2.4GHz Wireless Transceiver
3D print settings 3D print settings 3D print settings
image.2, 3 & 4 Checking the pins to use on the attiny44 and the pin functions
3D print settings
image.5 Defining the ATTINY44 in the SPI85.cpp
3D print settings
image.6 Binary sketch size: 5,024 bytes (of a 4,096 byte maximum)
3D print settings
image.7 The transmitter board
3D print settings
image.8 The receiver board

Next steps:

  • Make a board with the ATTINY 84
  • Test the board

Update
After continuing to work on the two boards and programming I have been able to get the RF24 to work with the ATTINY84. I rearranged the pins in my design so they would follow the example code found here. I couldn't change certain pins because they where hard coded in the libraries so it was easier to switch some pins in the design.

After creating the designs I soldered the components and used the code example to program the board with. The serial read was not working in my Arduino IDE and I didn't know why. I asked Dave to help me and he explained me the logic analyser so I could read out the pins on the FTDI Cable. It became clear to us we needed to switch around the MISO and MOSI and so we did by making a cable that would turn them around (we still do not know why we had to switch this around). After doing this, I was able to read out the correct data.

For the first test of the boards I used the ping_client and ping_server examples and edited it so they would work with the ATTINY84. This is something I already did for the mirf example, so this was quite easy. I just needed to set all the pins right and use the right libraries.

ping_client code

					
/*
 *  repo   : https://github.com/stanleyseow/arduino-nrf24l01/
 *  Author : Stanley Seow
 *  e-mail : stanleyseow@gmail.com
 *  date   : 8 Aug 2013
 *  Edited by : By Martin on 5 may 2014
 
 Some default values to take note when using this mirf/spi85 library
 Uses Mirf forked library from https://github.com/xdarklight/arduino-nrf24l01
 
 - node addressing is similar to RF24 libs but the bytes are flipped 
 
   byte TADDR[] = {0xe3, 0xf0, 0xf0, 0xf0, 0xf0}; will matches receiver node of RF24 below 
   const uint64_t pipes[2] = { 0x7365727631LL, 0xF0F0F0F0E3LL };
 
 The repo for the RF24 lib is at https://github.com/stanleyseow/RF24/
*/

#include <SPI85.h>
#include <Mirf.h>
#include <MirfHardwareSpi85Driver.h>
#include <nRF24L01.h>

// This USI was defined in SPI85.cpp
// Not to be confused with SPI (MOSI/MISO) used by ICSP pins
// Refer to page 61 of attiny84 datahseet
//
//#define USI-DO  5
//#define USI-DI  4
//#define USCK   6

#define CE    7    
#define CSN   3 

// ATMEL ATTINY84 / ARDUINO
//
//                           +-\/-+
//                     VCC  1|    |14  GND
//  SerialTx   (D  0)  PB0  2|    |13  AREF (D 10)
//             (D  1)  PB1  3|    |12  PA1  (D  9) 
//  RESET              PB3  4|    |11  PA2  (D  8) 
//  PWM  INT0  (D  2)  PB2  5|    |10  PA3  (D  7)  CE
//  SS/CSN     (D  3)  PA7  6|    |9   PA4  (D  6)  USCK
//  USI-DI     (D  4)  PA6  7|    |8   PA5  (D  5)  USI-DO
//                           +----+

int bufferSize = 0;
char buffer[32] = "";
unsigned int counter = 0; 
uint8_t nodeID = 0;

void setup(){
  
  Serial.begin( 9600 );    // for tiny_debug_serial 
  Mirf.cePin = CE;
  Mirf.csnPin = CSN;
  Mirf.spi = &MirfHardwareSpi85;
  Mirf.init();

  /*
   * Configure reciving address.
   */
   
  Mirf.setRADDR((byte *)"clie1");
  
  /*
   * Set the payload length to sizeof(unsigned long) the
   * return type of millis().
   *
   * NB: payload on client and server must be the same.
   */
   
  Mirf.payload = sizeof(unsigned long);
  
  /*
   * Write channel and payload config then power up reciver.
   */
   
  /*
   * To change channel:
   * 
   * Mirf.channel = 10;
   *
   * NB: Make sure channel is legal in your area.
   */
   
  Mirf.config();
  
  Serial.println("Beginning ... "); 
}

void loop(){
  unsigned long time = millis();
  
  Mirf.setTADDR((byte *)"serv1");
  
  Mirf.send((byte *)&time);
  
  while(Mirf.isSending()){
  }
  Serial.println("Finished sending");
  delay(10);
  while(!Mirf.dataReady()){
    //Serial.println("Waiting");
    if ( ( millis() - time ) > 1000 ) {
      Serial.println("Timeout on response from server!");
      return;
    }
  }
  
  Mirf.getData((byte *) &time);
  
  Serial.print("Ping: ");
  Serial.println((millis() - time));
  
  delay(1000);
} 
  
  
  
					
				

ping_server code

					
/*
 *  repo   : https://github.com/stanleyseow/arduino-nrf24l01/
 *  Author : Stanley Seow
 *  e-mail : stanleyseow@gmail.com
 *  date   : 8 Aug 2013
 *  Edited by : By Martin on 5 may 2014
 
 Some default values to take note when using this mirf/spi85 library
 Uses Mirf forked library from https://github.com/xdarklight/arduino-nrf24l01
 
 - node addressing is similar to RF24 libs but the bytes are flipped 
 
   byte TADDR[] = {0xe3, 0xf0, 0xf0, 0xf0, 0xf0}; will matches receiver node of RF24 below 
   const uint64_t pipes[2] = { 0x7365727631LL, 0xF0F0F0F0E3LL };
 
 The repo for the RF24 lib is at https://github.com/stanleyseow/RF24/
*/

#include <SPI85.h>
#include <Mirf.h>
#include <MirfHardwareSpi85Driver.h>
#include <nRF24L01.h>

// This USI was defined in SPI85.cpp
// Not to be confused with SPI (MOSI/MISO) used by ICSP pins
// Refer to page 61 of attiny84 datahseet
//
//#define USI-DO  5
//#define USI-DI  4
//#define USCK   6

#define CE    7    
#define CSN   3 

// ATMEL ATTINY84 / ARDUINO
//
//                           +-\/-+
//                     VCC  1|    |14  GND
//  SerialTx   (D  0)  PB0  2|    |13  AREF (D 10)
//             (D  1)  PB1  3|    |12  PA1  (D  9) 
//  RESET              PB3  4|    |11  PA2  (D  8) 
//  PWM  INT0  (D  2)  PB2  5|    |10  PA3  (D  7)  CE
//  SS/CSN     (D  3)  PA7  6|    |9   PA4  (D  6)  USCK
//  USI-DI     (D  4)  PA6  7|    |8   PA5  (D  5)  USI-DO
//                           +----+
int ledPinRed = 10;
int ledPinGreen = 8;
int ledPinBlue = 1;

int bufferSize = 0;
char buffer[32] = "";
unsigned int counter = 0; 
uint8_t nodeID = 0;

void setup(){
  
  Serial.begin( 9600 );    // for tiny_debug_serial 
  
  Mirf.cePin = CE;
  Mirf.csnPin = CSN;
  Mirf.spi = &MirfHardwareSpi85;
  Mirf.init();
  
  pinMode(ledPinRed, OUTPUT);
  pinMode(ledPinGreen, OUTPUT);
  pinMode(ledPinBlue, OUTPUT);

  Mirf.setRADDR((byte *)"serv1");
  
  /*
   * Set the payload length to sizeof(unsigned long) the
   * return type of millis().
   *
   * NB: payload on client and server must be the same.
   */
   
  Mirf.payload = sizeof(unsigned long);
  
  /*
   * Write channel and payload config then power up reciver.
   */
   
  Mirf.config();
  
  digitalWrite(ledPinRed, HIGH);
  digitalWrite(ledPinBlue, HIGH);
  digitalWrite(ledPinGreen, HIGH);
  
  Serial.println("Listening..."); 
}

void loop(){
  /*
   * A buffer to store the data.
   */
   
  byte data[Mirf.payload];
  
  /*
   * If a packet has been recived.
   *
   * isSending also restores listening mode when it 
   * transitions from true to false.
   */
   
  if(!Mirf.isSending() && Mirf.dataReady()){
    Serial.println("Got packet");
    
    /*
     * Get load the packet into the buffer.
     */
     
    Mirf.getData(data);
     if (data[0] == '1') {
      digitalWrite(ledPinRed, LOW);
      digitalWrite(ledPinBlue, HIGH);
      digitalWrite(ledPinGreen, HIGH);
     } 
     else if (data[0] == '2') {
      digitalWrite(ledPinRed, LOW);
      digitalWrite(ledPinBlue, LOW);
      digitalWrite(ledPinGreen, HIGH);
     } 
     else {
      digitalWrite(ledPinRed, LOW);
      digitalWrite(ledPinBlue, LOW);
      digitalWrite(ledPinGreen, LOW);
     }
    /*
     * Set the send address.
     */
     
     
    Mirf.setTADDR((byte *)"clie1");
    
    /*
     * Send the data back to the client.
     */
     
    Mirf.send(data);
    
    /*
     * Wait untill sending has finished
     *
     * NB: isSending returns the chip to receving after returning true.
     */
      
    Serial.println("Reply sent.");
  }
}  
  
  
					
				

Logic analyzer
Server board
Client board

Conclusion:
You really have to think everything through. I still feel with every step there is a possible bump you walk into. Overall, it's really a great learning process and it's just trial and error.

Conclusion v2:
There are still some mistakes that I made in creating the circuit board (connection wise). It is really important to check your board before you start milling it. I had a mistake where I put the GND instead of the VCC on the 4 pins LED connector for my RGB breakout board.

Next steps:

  • Make the serial.read work so I can send different light patterns to the server.
  • Redesign the boards double sided