Networking and Communications


Individual Assignment

Group Assignment
   Please check our Group Assignment page.

Skillsets Gained: Serial Communication between Arduino Uno and ATTiny 412
Software Used: Arduino IDE

Individual Final Group Files

Individual Assignment


In this week, I decided to simply connect my Arduino UNO board and the microcontroller with an ATTiny412 chip that I made in week 6. This assignment has referred to Jari's archive about this topic.
The core mechanism of this type of serial connection is to let the devices share the Tx and Rx input.

Serial Communication Mechanism
Serial Communication Mechanism

Node 1.Arduino Uno board


The first step is to program the Arduino Uno board to response to input node number.

The code are shown as below, which refered to Jari's archive.

a. Code
#include <SoftwareSerial.h >
SoftwareSerial mySerial(0, 1); // RX, TX

const char node = '1'; // network address
const int ledPin = 13; // the number of the LED pin, which is 13 for UNO board
int incomingByte;

void setup() {
mySerial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(1, INPUT);
}

void loop() {
if (mySerial.available() > 0) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
incomingByte = mySerial.read();
if (incomingByte == node) {
digitalWrite(ledPin, HIGH);
pinMode(1, OUTPUT); // open line to write
mySerial.print("node ");
mySerial.println(node);
pinMode(1, INPUT);
delay(200);
digitalWrite(ledPin, LOW);
}
}
}

b.Upload
In my case, I used the USB cable to connect the Arduino UNO board to the computer.
Tool>>Board: Arduino UNO >>Port: [COM #]>>Programmer: AVRISP mkll>>Upload

Arduino
Arduino UNO board

Node 2. ATTiny 412 Board


The second step is to program the microcontroller with an ATTiny412.
a.Determine connection
This board will be connected to the computer via the Arduino Board, so determining the right Pins to wire is an important procedure.
In my case, there are two sets of pincode mapping: (1) between ATTiny and the board and (2) between the board and UNO. Thus, both the ATTiny chip pin structure and how it is connected to the board need to be specified.

Board Structure
Board Structure

Based on the structures, in my case, the mapping between the Pins should be:
 ● GND: ATTiny412  Pin 8 - Board Pin  1 -UNO  GND
 ● VCC: ATTiny412  Pin 0 - Board Pin  3 - UNO  5V
 ● TX  : ATTiny412  Pin 3 - Board  Pin 4 - UNO  1(TX)
 ● RX  : ATTiny412  Pin 4 - Board   Pin 5 - UNO   0 (RX)

It is important to notice that difference between ATTiny Pin number and the board Pin number. I mistakenly used the board Pin number at first and get really strange outcomes.

b. Code
After determining the Pin number, the code for node 2 can be easily revised from the code of node 1.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3); // RX, TX (The ATTiny Pin number, NOT the board Pin number)

const char node = '2'; // network address
const int ledPin = 1; // the number of the LED pin

int incomingByte;
void setup() {
mySerial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
}

void loop() {
if (mySerial.available() > 0) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
incomingByte = mySerial.read();
if (incomingByte == node) {
digitalWrite(ledPin, HIGH);
pinMode(3, OUTPUT); // open line to write
mySerial.print("node ");
mySerial.println(node);

pinMode(3, INPUT);
delay(200);
digitalWrite(ledPin, LOW);
}
}
}

c.Upload and Connect
By connecting the board with USB cable, we can upload the code to the board.
Tool>>Board: ATTiny412... >>Port: [COM #]>>Programmer: >>Upload

ATTiny Upload
ATTiny Upload

Then, the USB cable should be removed and the board should be connected to the UNO board with jump wires.
  ● GND: Board Pin 1/ATTiny Pin 8 -> UNO GND
  ● VCC: Board Pin 3/ATTiny Pin 0 -> UNO 5V
  ● RX: Board Pin 5/ATTiny Pin 3 -> UNO 0
  ● TX: Board Pin 4/ATTiny Pin 4 -> UNO 1

Board Connection
Board Connection

Serial Communication


When the boards are connected to the computer, they are ready to be tested either with Arduino IDE or PuTTY.
I used the Arduino IDE Serial Monitor which can be evoked by clicking the icon the right-top corner.

Serial Monitor
Serial Monitor

By typing in the node number, the console will display the node name and the LED on the corresponding board will blink.


The communication part of the final project, which will involve the communication between mobile devices via Wi-Fi, will be updated when finished.



Networking and Communication in Final Project


Networking and communication has been an essential part for my final project, which is a clock that can automatically track the location change and inform the family members. There are two major lines of work in this process: (1) The Wi-Fi communication based on ESP8266 and (2)Serial Communication between ESP8266 and ATtiny 1614 controller.

Communication Mechanism
Communication Mechanism

ESP8266 Communication


The logic of this communication is straightforward, which is to acquire the GPS location from the mobile phone and then send the information to my clock.
ESP8266 serves as the core of this chain of communication:
Mobile Phone -> IF This Then That(IFTTT) ->Adafruit IO -> ESP8266.
This communication method was developed by our instructor Iván in his tutorial. Unlike the other previously available tutorials, this one is very friendly to the users who want to design their own board.
The previously existing tutorials tend to rely on commercial boards, such as Particle Photon or ESP8266 Dev board, which have their own specialized modules in IFTTT. Hence, it is hard to follow those tutorial if the users do not use the same commercial board.
The first step is to create an event with IFTTT which will create a trigger when I enter or leave an area.
1. Click the "+" sign next to "This"
2. Choose "Location" Module
3. Select the action
4. Create Trigger

IFTTT Setting
IFTTT Setting

The next step is to push the location change to Adafruit IO.
1. Click the "+" sign next to "That"
2. Choose "Adafruit"
This is where the other tutorials fail to support if the user uses self-made board. Because the commercial boards have their own module, like "Particle".
3. Send Data to Adafruit IO
4. Select the data type

IFTTT to Adafruit
IFTTT to Adafruit

The last step is to send the event to the ESP8266 via Wi-Fi.
The code I used are developed based on Iván's tutorial, which consisted of the a head file and the Wi-Fi communication file.
The major functions of this code include
- Connect to Wi-Fi
#define WIFI_SSID [replace with your own Wi-Fi SSID]
#define WIFI_PASS [replace with your own Wi-Fi Password]
- Connect to Adafruit IO and acquire the trigger
#define IO_USERNAME [replace with your own user name]
#define IO_KEY [replace with your own user name]
- Map each event to a location on the clock
// set up the feed
AdafruitIO_Feed *feed0 = io.feed("Home");
...
- Print the number that corresponding to the triggered location to the serial port
void handleMessage1(AdafruitIO_Data *data) {
// When received a position
Serial.println("1");//commute
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.
}
...
The full code is as below:

Adafruit_IFTTT_location


// Adafruit IO Subscription Example
//
// Adafruit invests time and resources providing this open source code.
// Please support Adafruit and open source hardware by purchasing
// products from Adafruit!
//
// Written by Todd Treece for Adafru
it Industries
// Copyright (c) 2016 Adafruit Industries
// Licensed under the MIT license.
//
// All text above must be included in any redistribution.
/*
Code written by Iván Sánchez Milara based on example code adafruitio_01_subscribe
Tutorials:
- https://learn.adafruit.com/using-ifttt-with-adafruit-io/
- https://learn.adafruit.com/adafruit-io-basics-esp8266-arduino/

This example code is in public domain.
*************************************************************
This example runs directly on NodeMCU.
Note: This requires ESP8266 support package:
https://github.com/esp8266/Arduino
And the following libraries:
- Adafruit IO Arduino
- Adafruit MQTT library
*************************************************************/
#include <ESP8266WiFi.h>
/************************** Configuration ***********************************/
//const int LED = 2;
// edit the config.h tab and enter your Adafruit IO credentials
// and any additional configuration needed for WiFi, cellular,
// or ethernet clients.
#include "config.h"
// set up the feed
AdafruitIO_Feed *feed0 = io.feed("Home");
AdafruitIO_Feed *feed1 = io.feed("Commute");
AdafruitIO_Feed *feed2 = io.feed("Work");
AdafruitIO_Feed *feed3 = io.feed("School");
AdafruitIO_Feed *feed4 = io.feed("Grocery");
AdafruitIO_Feed *feed5 = io.feed("Shopping");
AdafruitIO_Feed *feed6 = io.feed("Dinner");
AdafruitIO_Feed *feed7 = io.feed("Travel");
AdafruitIO_Feed *feed8 = io.feed("Vacation");
AdafruitIO_Feed *feed9 = io.feed("Neptune");
AdafruitIO_Feed *feed10 = io.feed("Emergent");
AdafruitIO_Feed *feed11 = io.feed("Exercise");
#define delay_time 500
const int LED=2;

void setup()
{

pinMode (LED, OUTPUT);
// start the serial connection
Serial.begin(9600);

// wait for serial monitor to open
while(! Serial);
//Serial.print("Connecting to Adafruit IO");

// start MQTT connection to io.adafruit.com
io.connect();

// set up a message handler for the count feed.
// the handleMessage function (defined below)
// will be called whenever a message is
// received from adafruit io.
feed0->onMessage(handleMessage0);
feed1->onMessage(handleMessage1);
feed2->onMessage(handleMessage2);
feed3->onMessage(handleMessage3);
feed4->onMessage(handleMessage4);
feed5->onMessage(handleMessage5);
feed6->onMessage(handleMessage6);
feed7->onMessage(handleMessage7);
feed8->onMessage(handleMessage8);
feed9->onMessage(handleMessage9);
feed10->onMessage(handleMessage10);
feed11->onMessage(handleMessage11);
// wait for an MQTT connection
// NOTE: when blending the HTTP and MQTT API, always use the mqttStatus
// method to check on MQTT connection status specifically
// while(io.mqttStatus() < AIO_CONNECTED) {
//Serial.print(".");
digitalWrite (LED, HIGH); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, LOW); // Making LED LOW.
delay(500);
//delay(500);
// }
// Because Adafruit IO doesn't support the MQTT retain flag, we can use the
// get() function to ask IO to resend the last value for this feed to just
// this MQTT client after the io client is connected.
feed0->get();
feed1->get();
feed2->get();
feed3->get();
feed4->get();
feed5->get();
feed6->get();
feed7->get();
feed8->get();
feed9->get();
feed10->get();
feed11->get();
// we are connected
//Serial.println();
//Serial.println(io.statusText());
digitalWrite (LED, LOW); // Making LED High.
}
void loop()
{
// io.run(); is required for all sketches.
// it should always be present at the top of your loop
// function. it keeps the client connected to
// io.adafruit.com, and processes any incoming data.
io.run();

// Because this sketch isn't publishing, we don't need
// a delay() in the main program loop.

}
// this function is called whenever a 'feed' message
// is received from Adafruit IO. it was attached to
// the counter feed in the setup() function above.
void handleMessage0(AdafruitIO_Data *data) {
// When received a position
Serial.println("0");//home
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.


}
void handleMessage1(AdafruitIO_Data *data) {
// When received a position
Serial.println("1");//commute
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage2(AdafruitIO_Data *data) {
// When received a position
Serial.println("2");//work
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage3(AdafruitIO_Data *data) {
// When received a position
Serial.println("3"); //school
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage4(AdafruitIO_Data *data) {
// When received a position
Serial.println("4");//grocery
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage5(AdafruitIO_Data *data) {
// When received a position
Serial.println("5");//shopping
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage6(AdafruitIO_Data *data) {
// When received a position
Serial.println("6");//dinner
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage7(AdafruitIO_Data *data) {
// When received a position
Serial.println("7");//travel
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage8(AdafruitIO_Data *data) {
// When received a position
Serial.println("8");//vacation
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage9(AdafruitIO_Data *data) {
// When received a position
Serial.println("9");//Neptune
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage10(AdafruitIO_Data *data) {
// When received a position
Serial.println("10");//emergent
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}
void handleMessage11(AdafruitIO_Data *data) {
// When received a position
Serial.println("11");//exercise
digitalWrite (LED, LOW); // Making LED High.
delay(500); // Some Delay
digitalWrite (LED, HIGH); // Making LED LOW.

}



ESP8266 Board
ESP8266 Board

My design of the ESP8266 contains a slide switch that has a program position and a connect position. The slide switch should be turned to the program position when uploading the code. After the code is successfully uploaded, turn the slide switch to the connect position and press the reset button, then the ESP8266 board is ready to be used.

Functioning
Functioning

When the ESP8266 board is connected, it can receive te push from the Adafruit IO system.
For test and demonstration purposes, I have used the Adafruit IO dashboard to simulate the location change. When the event is turned ON and OFF the corresponding numbers are printed into the serial port.

ESP8266-ATtiny 1614 Serial Communication


ESP8266-ATtiny1614
ESP8266-ATtiny1614

The ESP8266 board and ATTINY 1614 board should have these pins connected in this way:
●VCC - VCC
●GND - GND
●TX - TX
●RX - RX

The numbers of triggered event is then send from the ESP8266 board to the ATtiny 1614 microcontroller, which then drives the motor to move to the corresponding postions.
The critical code to achieve this goal is as below:
The code in the void loop() reads the serial input from ESP8266. As the Serial.Read() function reads single byte in ASCII format, the input information needs to be further processed to let the ATtiny 1614 to receive the actual numbers.
moveToLocation() function is the actual code that drives the motor.
More details about the code can be found here.

Critical Episodes of the Code

//Move to position
void moveToLocation(int location){
num_of_steps = (location - current_location)*4; // Each location is 30 degrees. You have then 4 steps per locations

current_location = location;
Serial.print("steps: ");
Serial.println(num_of_steps);
step (num_of_steps);
}
...
void loop() {

// put your main code here, to run repeatedly:
//for location10, 11 and 12, which are more than 1 byte
while (Serial.available()>0) {
int inChar = Serial.read();
if (isDigit(inChar)) {
// convert the incoming byte to a char and add it to the string:
inString += (char)inChar;
}
// if you get a newline, print the string, then the string's value:
if (inChar == '\n') {
//Serial.print("Value:");
int location = inString.toInt();
inString = "";//
...
}
}
}



Group Assignment


This week's group assignment is to send a message between two projects。 Our group used 3 ATtiny 412 boards that were made in a previous week as different nodes.
In order to more conveniently connect the boards, we referred to Jari's archive and resued his design of Rx/Tx Hub (Trace.rml, Outline.rml).

Rx/Tx Hub
Rx/Tx Hub

After milling and soldering the hub, we connected the 3 boards with the hub.

Connection
Connection

We reused the the code for serial communication, which sends the message several times through the network.

Node Sample
The number after "const char node" has been changed for different nodes.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3); // RX, TX (The ATTiny Pin number, NOT the board Pin number)

const char node = '1'; // network address
const int ledPin = 1; // the number of the LED pin

int incomingByte;
void setup() {
mySerial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
}

void loop() {
if (mySerial.available() > 0) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
incomingByte = mySerial.read();
if (incomingByte == node) {
digitalWrite(ledPin, HIGH);
pinMode(3, OUTPUT); // open line to write
mySerial.print("node ");
mySerial.println(node);

pinMode(3, INPUT);
delay(200);
digitalWrite(ledPin, LOW);
}
}
}

Functioning
Functioning

Files


Arduino Code:
Individual:  ●   Place holder  ●   Place holder
Group:  ●   Analog Detection