Week 15 - Networking and Communications

Contents

Program

First of all, following my week13 work, I made 2x3 flat cable and connected serially like this to communicate with each node I made in week13.

It would provide 5V, GND, SCL and SDA so only 4 out of 6 pins work. In the picture, the bread board was just able to be pull-up and power bridge. And Arduino UNO would have been temporary TWI/I2C master.

I was looking for I2C libraries on Attiny44A. Many thanks svoisen who contributed a really awesome modified library to support ATtiny44. With Arduino IDE and ATtiny capable library, I completed a sample demo here with sending data from computer to Arduino UNO through serial, and Arduino UNO would tranlate and send to direct node over I2C.

Slave code
// Get this from https://github.com/rambo/TinyWire
#include <TinyWireS.h>

#define I2C_SLAVE_ADDRESS 0x01 // the 7-bit address (remember to change this when adapting this example)

uint8_t incomingByte;   // for incoming serial data

uint8_t pwm;

void receiveEvent(uint8_t howMany)
{
    if (howMany < 1)
    {
        // Sanity-check
        return;
    }
    if (howMany >= 2)
    {
        // Also insane number
        return;
    }

    incomingByte = TinyWireS.receive();

    pwm = map(incomingByte, 0, 180, 5, 24);
}

void setup()
{
  TCCR0A = (1 << COM0B1) | (0 << COM0B0) | (0 << WGM01) | (1 << WGM00); // clear OC0B on compare match
  TCCR0B = (1 << CS02) | (0 << CS01) | (1 << CS00) | (1 << WGM02); // prescaler /8, phase and frequency correct PWM, OCRA TOP

  TCNT0 = 0x00;
  OCR0A = 0xC3;
  OCR0B = 0x05;

  PORTA |= (1 << PA7);
  DDRA |= (1 << PA7);

  TinyWireS.begin(I2C_SLAVE_ADDRESS);
  TinyWireS.onReceive(receiveEvent);
}

void loop()
{
  /**
   * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716)
   * it needs to be called in a very tight loop in order not to miss any.
   * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop.
   */
  TinyWireS_stop_check();

  OCR0B = pwm;
}
Master code
/*   DA Lamp (documentation assistant lamp)
 *    
 *   In v1, we are sending commands including servo motor index and angles from computer serial to Arduino/Satshakit, and Arduino/Satshakit would 
 *   becaome an I2C master controlling servo motors.
 *   
 *   By Kevin Cheng
 *   Fablab Taipei, Taiwan.
 *   
 *   DA Lamp project under the MIT license.
 */

#include <Wire.h>

String inputString = "";

uint8_t indexServo;
uint8_t angle;

boolean stringComplete = false;  // whether the string is complete

void setup() {
  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
  Wire.begin();
  inputString.reserve(200);
}

void loop() {

  if (stringComplete) {
    indexServo = inputString.substring(0,inputString.indexOf(',')).toInt();
    angle = inputString.substring(inputString.indexOf(',')+1).toInt();

    Serial.print("Sending to ");
    Serial.print(indexServo);
    Serial.print(" and ");

    sendToServo(indexServo, angle);

    inputString = "";
    indexServo = 0;
    
    stringComplete = false;
  }
}

void sendToServo(int index, uint8_t angle) {
  Wire.beginTransmission(index); // transmit to device #2
  Wire.write(angle);  // sends one byte
  Wire.endTransmission();  // stop transmitting
  Serial.print("turning to ");
  Serial.print(angle);
  Serial.print("\n");      
}


void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();

    inputString += inChar;

    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
Result