W15,16: Final Project.

What does it do?




Initial plan was to make toys for toddlers but could not make big capacitive switch work and shifted idea a bit.
Objective:
My son (1.5 years old) started to interact with digital contents e.g. YouTube video.
I would like to provide him or children of relevant age physical interface to interact easily and in an enjoyable way with digital contents.

Goal:
Make tangible switches which can control digital contents, sounds, or whatever.

Who's done what beforehand?/ What did you design?
Makey Makey (https://www.kickstarter.com/projects/joylabs/makey-makey-an-invention-kit-for-everyone) changes anything into a switch.
I have not seen any wall-paper type of implementation.

What materials and components were used?/ How much did they cost?/ Where did they come from?

Materials:
It costed around $20 (but not sure about the exact price of plywood board and copper sheet since I used lab materials.).
  • AVR microcontroller (ATTiny 44), connectors, capacitors, resistors
  • Bluetooth module (HC-05)
  • 9V battery
  • Plywood board
  • Copper sheet


Software:
  • Eagle for the board design
  • Arduino IDE for AVR programming (though have not used Arduino library)
  • AutoCAD for the cube design
  • Node.js for a web server which listen to a serial port


Main board
Cube design on AutoCAD

What parts and systems were made?/ What processes were used?
  • AVR board with 8 ch of capacitive switch input and TX serial communication port with 3.3v power supply
  • AVR program which controls capacitive switch inputs and serial outputs
  • Capacitive switches (key, cube)
  • Node.js (+ Serial-to-socketio library by Tomer)
  • HTML and JavaScript for audio

Node.js reading the serial inputs and transmitting the value to the web page


What questions were answered?
  • Capacitive switch can be implemented in different designs (cubes, flat etc)
  • AVR can talk easily to other devices over Bluetooth (though it is still unstable)
  • Node.js can easily receive serial communication from AVR using Socket.IO and serial port library (though it seems to have some delay and loss).

How was it evaluated?/ What are the implications?
  • Integrated implementation of laser cut, embedded programming, inputs/outputs/network, application programming
  • I will try further projects of things which talks to Internet.








Detail follows below...


Project Components

ATtiny listens to capacitive switch
ATtiny talks to WiFi module over serial

1. Get familiar with Arduino IDE
2. Control Wireless module with ATtiny44
3. SoftwareSerial.h - size concern
Serial communication over Bluetooth module
Capacitive sensing with AVR
Design and mill the board
Serial communication on Node.js
HTML5 audio

iPhone cradle
Design on AutoCAD
Lasercut


1. Get familiar with AVR programming with Arduino IDE
I started to reprogram my boards on previous embedded programming and network week. Though I installed and set up Arduino IDE before, it was the first time to use for programming through this course. I thought using Arduino IDE and Arduino library would save some time on the final project.

1-1. Reprogram the embedded programming board with Arduino IDE
a. Arduino IDE> Example> Basics> Blink.
I started with running the basic LED blinking function butI could not make the board work properly though the program writing seems to be normally done. It turned out that I assigned wrong pin numbers.

When we use Arduino library, we should assign the numbers Pin X (1-10) below instead of assigning the numbers from 1 to 14. (Refer to the column “corresponding Arduino Pin Number” below when programing ATtiny44/84 on Arduino IDE.)
http://academy.cba.mit.edu/content/tutorials/akf/embedded_programming_arduinoIDE.html
Other resources:
Programming an ATtiny w/ Arduino 1.0 - high-low tech http://highlowtech.org/?p=1695
Here are nice graphics of pin assignments http://www.pighixxx.com/test/pinoutspg/processors/

b. Serial Communication
I ran serial communication code I prepared. I received continuous wired characters.
TX = AVR PIN 12 (connect to FTDI cable RX)
RX = AVR PIN 13 (connect to FTDI cable TX)
SoftwareSerial mySerial(13, 12) //RX, TX

UART hardware serial communication tutorial http://www.appelsiini.net/2011/simple-usart-with-avr-libc

2. Control WiFi module (ESP8266) with ATtiny44 over Serial

a. Try controlling WiFi module over serial by Arduino IDE programming (failed)
How to use SoftwareSerial.h
I referred to the basic tutorial about how to use serial communication on Attiny.

Another tutorial here.
---------

#include <SoftwareSerial.h>
const int rx=3;
const int tx=1;

SoftwareSerial mySerial(rx,tx);
int i=0;
char buf[12];

---------

---------
void setup() {
pinMode(rx,INPUT);
pinMode(tx,OUTPUT);
mySerial.begin(9600);
}
---------
void loop() {
if (mySerial.available()>0){
buf[i]= mySerial.read(); //

if (int(buf[i])==13 || int(buf[i])==10 ){ //If Carriage return has been reached
mySerial.println(buf);

for(int x=0;x<=10;x++){
buf[x]=' ';
}

i=0; //start over again
}

i++;
}
}
---------

It seemed that the program size was too big when I use SoftwareSerial.h. I examined the size of the code line by line as described below.

Just adding mySerial.begin(9600) gave me the error.


700 bytes
- SoftwareSerial mySerial(0,1); (+ 1,522 bytes)

2,222 bytes

Memory size Issues using String on ATtiny programming are described here.

I measured the memory usage by adding/deleting the code line by line.

+ String GET = "GET /update?key=[THINGSPEAK_KEY]&field1=";
2,222 bytes -> 3,632 bytes (+1,410 bytes)

+ mySerial.begin(9600);
2,222 bytes -> 2,772 bytes (+550 bytes)

delay(5000); // +226 bytes (2,998bytes)
mySerial.println(“AT”) // +176 bytes (3,174bytes)

if(mySerial.find("OK")){
connectWiFi();
}
boolean connectWiFi(){
} // +376bytes (3,550bytes)

mySerial.println("AT+CWMODE=1"); // 22 bytes
delay(2000); // 10 bytes
// +32bytes (3,582bytes)

mySerial.println("AT+CWJAP=\"SSID\",\"PASS\"”); //+40bytes (3,622bytes)

delay(5000); // 10 bytes
if(mySerial.find("OK")){
return true;
}else{
return false;
} // 8 bytes
// +18bytes (3,640bytes)

void loop() {
updateTouch();
}
void updateTouch (){
}
// adding a function did not affect the size of the code +0bytes

delay(60000); // +10 bytes (3650b)
mySerial.println("AT+CIPSTART=\"TCP\",\"184.106.153.149\",80”); // +54b (3704b)


a. Try serial communication from scratch on AVR using regular make commands and light weight libraries

Here are commands to compile, burn the fuses, and upload the program.
make -f xxx.c.make
sudo make -f xxx.c.make program-usbtiny-fuses
sudo make -f xxx.c.make program-usbtiny

I should prepare xxx.c.make and xxx.c. The commands above will generate xxx.out and xxx.hex.
Here is how the make file looks like.
-----
PROJECT=hello.ftdi.44.echo
SOURCES=$(PROJECT).c
MMCU=attiny44
F_CPU = 20000000

CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU)

$(PROJECT).hex: $(PROJECT).out
avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\
avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out

$(PROJECT).out: $(SOURCES)
avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program-usbtiny: $(PROJECT).hex
avrdude -p t44 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex

program-usbtiny-fuses: $(PROJECT).hex
avrdude -p t44 -P usb -c usbtiny -U lfuse:w:0x5E:m
-----




#include <SoftwareSerial.h>
#define SSID "[YOUR_SSID]"
#define PASS "[YOUR_PASSWORD]"
#define IP "184.106.153.149" // thingspeak.com
String GET = "GET /update?key=[THINGSPEAK_KEY]&field1=";
SoftwareSerial mySerial(10, 11); // RX, TX

void setup()
{
mySerial.begin(9600);
sendDebug("AT");
delay(5000);
if(mySerial.find("OK")){
mySerial.println("RECEIVED: OK");
connectWiFi();
}
}

void sendDebug(String cmd){
mySerial.print("SEND: ");
mySerial.println(cmd);
}

boolean connectWiFi(){
Serial.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
sendDebug(cmd);
delay(5000);
if(Serial.find("OK")){
mySerial.println("RECEIVED: OK");
return true;
}else{
mySerial.println("RECEIVED: Error");
return false;
}
}


b. Upload data to a remote web server


Spiral 1
Use node.js to read serial communication on my laptop (Mac OS X)
Serial to web tutorial by Tomer Weller https://github.com/tomerweller/serial-to-socketio
the tutorial demonstrate how to implement a thin proxy server in node.js (using Express.js) that relays data to/from the serial port from/to web clients via socket.io.

Socket.io (dot install. in Japanese)
http://dotinstall.com/lessons/basic_socketio

Install socket.io
npm istall socket.io

send(emit), listen(on)


Control WiFi module by serial communication from a laptop
Done

Control WiFi module by serial communication from a microcontroller
Started from the code here: http://www.instructables.com/id/ESP8266-Wifi-Temperature-Logger/all/?lang=ja

The program is composed of:
void setup()
- initiate serial communication with the WiFi module
- call connectWiFi() to connect to a WiFi AP

void loop()
- periodically monitoring the capacitive switch using delay
- call updateTouch() to send values to the remote server

void updateTouch()
- send the value to the remote server
- using AT commands over serial communication

boolean connectWiFi()
- Initiate the WiFi connection using AT commands over serial communication

#include <stdlib.h>
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);</p><p>
#define SSID "[YOUR_SSID]"
#define PASS "[YOUR_PASSWORD]"
#define IP "184.106.153.149" // thingspeak.com
String GET = "GET /update?key=[THINGSPEAK_KEY]&field1=";
SoftwareSerial monitor(10, 11); // RX, TX

void setup()
{
monitor.begin(9600);
Serial.begin(9600);
sensors.begin();
sendDebug("AT");
delay(5000);
if(Serial.find("OK")){
monitor.println("RECEIVED: OK");
connectWiFi();
}
}

void loop(){
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
tempC = DallasTemperature::toFahrenheit(tempC);
char buffer[10];
String tempF = dtostrf(tempC, 4, 1, buffer);
updateTemp(tempF);
delay(60000);
}

void updateTemp(String tenmpF){
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
delay(2000);
if(Serial.find("Error")){
monitor.print("RECEIVED: Error");
return;
}
cmd = GET;
cmd += tenmpF;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
Serial.println(cmd.length());
if(Serial.find(">")){
monitor.print(">");
monitor.print(cmd);
Serial.print(cmd);
}else{
sendDebug("AT+CIPCLOSE");
}
if(Serial.find("OK")){
monitor.println("RECEIVED: OK");
}else{
monitor.println("RECEIVED: Error");
}
}
void sendDebug(String cmd){
monitor.print("SEND: ");
monitor.println(cmd);
Serial.println(cmd);
}
boolean connectWiFi(){
Serial.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
sendDebug(cmd);
delay(5000);
if(Serial.find("OK")){
monitor.println("RECEIVED: OK");
return true;
}else{
monitor.println("RECEIVED: Error");
return false;
}
}



Capacitive touch sensing with AVR
Capacitive touch sensing with AVR and a single ADC pin http://tuomasnylund.fi/drupal6/content/capacitive-touch-sensing-avr-and-single-adc-pin
Matt Blackshaw’s Touchpad http://fab.cba.mit.edu/classes/MIT/863.10/people/matt.blackshaw/week8.html

I tweaked the code to transform the pad to 8 keys piano and large touchpad.
I designed the board from scratch with 3.3v regulators.

First I could not mill the board properly since I set the export image resolution as 150 dpi. 500 dpi worked fine on the second trial.


Read serial communication with node.js




Install node.js serialport library
I got an error somehow when I run ’npm install.’ I changed the current directory to /node_modules. Installed necessary libraries.
cd /usr/local/lib/node_modules
npm install serialport
npm install glob
npm install socket.io

I cloned Amir’s serial2web project, which provides a thin proxy server in node.js that relays data to/from the serial port from/to web clients via socket.io: https://github.com/amirlazarovich/serial2web.git
git clone https://github.com/amirlazarovich/serial2web.git

I run the example code and encountered an error.
node app

module.js:340
throw err;
^
Error: Cannot find module 'glob'

Added the code below.
12: require.main.paths.push('/usr/local/lib/node_modules');

Rerun the code but still gets an error.


I cloned Tomer’s serial-to-socketio project, which provides a thin proxy server in node.js that relays data to/from the serial port from/to web clients via socket.io: https://github.com/tomerweller/serial-to-socketio.git
git clone https://github.com/tomerweller/serial-to-socketio.git

Added the code below.
12: require.main.paths.push('/usr/local/lib/node_modules');

I changed some lines of codes to read the data properly.
node app <serial/bluetooth port>


Preparing Piano Sound
I found this on freesound.org http://www.freesound.org/people/pinkyfinger/packs/4409.
I converted the .wav file to .ogg file with Switch Audio File Converter (NCH Software) when necessary. http://www.nch.com.au/switch/index.html



Groceries
Case Design Guidelines for iPhone https://developer.apple.com/resources/cases/Case-Design-Guidelines.pdf
Capacitive Touch Sensing with AVR and a Single ADC Pin http://tuomasnylund.fi/drupal6/content/capacitive-touch-sensing-avr-and-single-adc-pin
Touch sensor on AVR, done without Qtouch library http://blog.aleksander.kaweczynski.pl/touch-sensor-on-avr-done-without-qtouch-library/
Arduino and the realtime web (Socket.io - Arduino connections) http://www.slideshare.net/andrewjfisher/arduino-and-the-real-time-web
Past projects: Instructables // interactive living wall http://www.instructables.com/id/Create-an-Interactive-Living-Wall/?ALLSTEPS
http://www3.big.or.jp/~schaft/hardware/bootloader_sketch/page008.html

Raspberry Pi, NodeJS and basic electronics http://blog.fxndev.com/raspberry-pi-and-led-fun/
Raspberry Pi capacitive touch sensors https://learn.adafruit.com/capacitive-touch-sensors-on-the-raspberry-pi/programming
Raspberry Pi NodeJS and RGB LED http://tomowatanabe.hatenablog.com/entry/2013/01/21/221722