0% found this document useful (0 votes)
2K views1,991 pages

110 Fun Projects With Arduino

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2K views1,991 pages

110 Fun Projects With Arduino

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

110 Fun Projects with Arduino

1) Arduino Hacking STEM Electroconductivity


Meter

COMPONENTS AND SUPPLIES

biodegradable straw
× 1

coffee stir stick × 2


stainless steel wire (28 gauge,
17cm) × 2

pin-ended alligator clips


× 2

Resistor 100 ohm


× 1

Arduino UNO & Genuino UNO


× 1

USB-A to B Cable
× 1
NECESSARY TOOLS AND MACHINES
scissors

Wire Stripper & Cutter, 18-10 AWG /


0.75-4mm² Capacity Wires

Hot glue gun (generic)

Tape, Clear

ruler
APPS AND ONLINE SERVICES
Microsoft Data Streamer

Arduino IDE

Microsoft Excel

ABOUT THIS PROJECT

This project aimed to meet the requirements of the


science fair that happened in my city Our
electroconductivity sensor was designed as a simple
way to measure the amounts of dissolved substances
in different water samples. It can also be used as a
(short-term) soil moisture sensor!
This sensor is made of two wires separated by an air
gap. The air gap allows us to test how well a material
or substance conducts electricity.
Build an Electroconductivity Meter
Mark your straw at 14 cm. Cut at your mark.

Next, mark both of your coffee stir sticks at 13 cm and


make cuts.

Using your hot glue gun, run a thin line of glue along
the length of one of your stir sticks.
Quickly press the sticks together until the glue has
cooled.

Measure and cut two lengths of 17 cm stainless steel


wire. Straighten out the wires the best you can.

Place the wire on the stir stick so that it is centered


and the ends extend about 1.75 cm beyond the stir
stick.
Center your other wire opposite the first. Tape the
wires onto the stir sticks.

Tape the middle and opposite ends of the sticks to


hold the wire in place keeping the wires centered on
the sticks.

Push the stir sticks with wire into your 14 cm straw.


Measure to make sure your wires stick out of the end
of the straw at the 1.5 cm mark.

Dab some hot glue inside both ends of the straw.

Measure and cut your other length of straw at 4 cm


Cut the 4cm straw in half, then dab some hot glue on
the end and...

... attach to the end of the straw! This will act as a


shield guard for the sensor wire ends.

Bend the longer ends of the wire as shown in the


photo above. This gives the alligator clips a better
connection once attached.
Attach alligator clips to the bent wires. Awesome!
You’ve completed the EC sensor. You care now ready
to connect to your microcontroller.
Connect your alligator clips to the Arduino Uno as
shown in the Attachments section.
If you are comfortable writing Arduino code, use the
analog input pins to measure the voltage changes
across the EC sensor. You are also welcome to use our
sketch which is provided in the Attachments section.

SCHEMATICS

A Fritzing Diagram showing the electrical connections


from the EC Sensor wires to the Arduino analog input
pin A0.
CODE

// CONSTANTS / SETTINGS

const byte POWER_PIN = 2; // Digital pin to use for powering


pulse circuit
const byte EC_PIN = A0; // Analog pin used to read EC Meter
volage

const int READ_DURATION = 100; // Amount of time to take


reading for (ms)
const int READ_INTERVAL = 6000; // Amount of time between
readings (ms)

const String SERIAL_OUTPUT_DELIMITER = ","; // Cordoba expects


a comma-delimited string
const int SERIAL_OUTPUT_INTERVAL = 175; // Amount of time
between serial outputs

// TIMESTAMPS
unsigned long currentTime = 0;
unsigned long readStartTime = 0; // Time that the EC Meter read
process starts
unsigned long lastOutputTime = 0; // Time of last serial output

// SENSORS

float ecMeterReading = 0;
float ecMeterVoltage = 0;

void setup() {
Serial.begin( 9600 );

pinMode( POWER_PIN , OUTPUT );


}

void loop() {
currentTime = millis();

// Read Sensors
// Check for start read time
if ( currentTime - readStartTime >= READ_INTERVAL ){ // Initialize
EC Meter read sequence
readStartTime = currentTime; // Set start time
}
else if ( currentTime - READ_DURATION <= readStartTime ) // Power
Up / Read
{
startPower( POWER_PIN ); // Start charging solution
delay(250); // Delay until fully charged
readSensors(); // Take sensor readings
delay(250);
} else { // Power Down
stopPower( POWER_PIN ); // Stop charging and let
solution depolarize
}

writeToSerial();
}

/*
------------------------------------------------------------------------------------------
-------------
SENSOR/ARDUINO PROCESSING
------------------------------------------------------------------------------------------
-------------
*/

void startPower( byte pin ){


digitalWrite( pin , HIGH );
}

void stopPower ( byte pin ){


digitalWrite( pin , LOW );
}

void readSensors() {
ecMeterReading = analogRead( EC_PIN ); // read the voltage from
the EC Meter
ecMeterVoltage = ecMeterReading * 5.0;
ecMeterVoltage = ecMeterVoltage / 1024;
}

/*
------------------------------------------------------------------------------------------
-------------
OUTGOING SERIAL DATA TO EXCEL PROCESSING CODE
------------------------------------------------------------------------------------------
-------------
*/

void writeToSerial()
{
// Ignore if not within output interval
if ( currentTime - lastOutputTime < SERIAL_OUTPUT_INTERVAL ) {
return;
}
Serial.print( ecMeterVoltage , 4 );
Serial.print( SERIAL_OUTPUT_DELIMITER );

Serial.println();

lastOutputTime = currentTime;
}

2) Arduino Cockroach Laser Killer


COMPONENTS AND SUPPLIES

Arduino Nano R3
× 1

SG90 Micro-servo motor


× 1
LDR sensor × 1

Resistor 10k ohm


× 1

Jumper wires (generic)


× 1

Breadboard (generic)
The 170 points breadboard × 1

9V battery (generic)
× 1

9V Battery Clip
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

If you feel terrified about cockroaches...


You problem is now solved with " Cockroach Laser
Killer!
No more embarrassing excuses to run off from them!

Okay...this is a simple LDR and Servo interaction. Geta


laser pen and "shoot" at the target. LDR activates a servo
motor to drop your target down. 3 seconds later it goes
up again for another shot.
The main issue is to set the correct threshold of the LDR
sensor and avoid unwanted movements due to light
conditions.
A
7cm x 7cm box.
The inital setup. When energized, the servo lifts the
target.
The target arised and the laser gun!
Creepy!
In the box with a smal breadboard.

SCHEMATICS
CODE

/*
Project - Interaction LDR x Servo
*/
#include <Servo.h>

Servo servo1; // Servo object

int pinServo = 2; // variable to store the servo position


int triggerPoint = 970; //trigger point to start servo
byte sensor = A0;
int sensorValue;

void setup() {
pinMode(pinServo, OUTPUT);
servo1.attach(pinServo); // attaches the servo pin
servo1.write(155);// tell servo to go to "up" position
delay(200);
pinMode(sensor, INPUT);
}

void loop() {
sensorValue = analogRead(sensor);
if (sensorValue > triggerPoint){
servo1.write(75); // tell servo to go to "down" position
delay(3000);
servo1.write(155);
delay(200);
}
}//End loop
3) Controlled Board Eraser Using Arduino and
1Sheeld

COMPONENTS AND SUPPLIES


Android device × 1
Arduino UNO & Genuino UNO
× 1

1Sheeld
× 1

Micro Metal DC motor kit


× 2

L298 Dual H-Bridge Motor


Driver × 1

Magnetic Disk
× 2

LED (generic)
× 1
NECESSARY TOOLS AND MACHINES

Magnetic Board Eraser

ABOUT THIS PROJECT

Are you tired of erasing the board every time you use it.
Have you ever thought of erasing the whole board while
you are sitting in your place. The automatic board eraser
is a normal magnetic board eraser with motors and
wheels that can easily erase and clean your board using
your mobile phone. Just leave it mounted on the board
and use it when you need to erase.

Why did i decide to make it ?

Most of the people nowadays use white boards in classes


or meeting rooms. They write a lot and erase every time
when they finish. There are some disadvantages from
erasing the whole board physically with your hand, like
wasting some time, doing effort, not professional in
some meetings for important people to do it themselves
and it the eraser makes your hands more dirty after using
it. Moreover, some people find it hard to reach all the
parts of the board especially when it is mounted on a
high distance from the ground. As a result, I decided to
build a small magnetic automated board eraser with
wheels so i could control it easily from my mobile phone
to erase the board from my place.

How Does it work?

After connecting all the hardware components and


uploading the code to the arduino and 1sheeld start
opening the 1sheeld mobile application and connect it to
the 1sheeld board via Bluetooth. Then you have to select
the shields that we will use; they are the game pad shield
and accelerometer shield. Put the eraser on the board and
open the game pad shield and start using the four arrow
directions to move up, down, left or right. An LED will
be high when the magnetic eraser moves on the board to
start erasing words. Another way to control this eraser is
to open the accelerometer shield and hold the phone in
your hand. If you want to move up tilt your hand in the
front direction to make the Y < -5, so the eraser will
move up. If you want to move down tilt your hand in the
backward direction to make the Y < 6, so the eraser will
move down. Furthermore, if you want to move right tilt
your hand in the right direction to make the x < -6, so the
eraser will move in the right direction and finally If you
want to move left tilt your hand in the left direction to
make the x > 6, so the eraser will move in the left
direction. Now your board will be easily controlled to
erase the whole board without doing any effort.

Images of hardware Components

Magnetic Board Eraser


Micro metal DC motors and wheels
Motor Driver L289n
Motors connected to motor driver
1sheeld Board
Gloves used to control the board eraser using mobile
accelerometer
Top view of the Eraser

Game pad used to control the eraser


Magnetic Board Eraser Final Prototype

SCHEMATICS
CODE

#define CUSTOM_SETTINGS
#define INCLUDE_GAMEPAD_SHIELD
#define INCLUDE_LED_SHIELD
#define INCLUDE_ACCELEROMETER_SENSOR_SHIELD

float x, y, z;

/* Include 1Sheeld library. */


#include <OneSheeld.h>

/* A name for the LED on pin 7. */


const int ledPin = 13;

/* Pin configuration of the Seeedstudio's motor shield. */


int motorAPin1 = 8;
int motorAPin2 = 11;
int motorBPin1 = 12;
int motorBPin2 = 7;
int motorASpeedPin = 9;
int motorBSpeedPin = 10;

void setup()
{
/* Start communication. */
OneSheeld.begin();
/* Set the LED pin as output. */
pinMode(ledPin, OUTPUT);

/* Seeedstudio's motor shield initialization. */


pinMode(motorAPin1, OUTPUT); // IN1 of motor A
pinMode(motorAPin2, OUTPUT); // IN2 of motor A
pinMode(motorBPin1, OUTPUT); // IN3 of motor B
pinMode(motorBPin2, OUTPUT); // IN4 of motor B
pinMode(motorASpeedPin, OUTPUT); // Speed of motor A
pinMode(motorBSpeedPin, OUTPUT); // Speed of Motor B
}

void loop()

{ x=AccelerometerSensor.getX();
y=AccelerometerSensor.getY();
z=AccelerometerSensor.getZ();

/* If up is pressed, move the car forward. */


if (GamePad.isUpPressed()|| y < -5)
{
analogWrite(motorASpeedPin, 255);
analogWrite(motorBSpeedPin, 255);
digitalWrite(motorAPin1, LOW);
digitalWrite(motorAPin2, HIGH);
digitalWrite(motorBPin1, LOW);
digitalWrite(motorBPin2, HIGH);
digitalWrite(ledPin, HIGH);
}
/* If down is pressed, move the car backwards. */
else if (GamePad.isDownPressed()|| y > 6)
{
analogWrite(motorASpeedPin, 255);
analogWrite(motorBSpeedPin, 255);
digitalWrite(motorAPin1, HIGH);
digitalWrite(motorAPin2, LOW);
digitalWrite(motorBPin1, HIGH);
digitalWrite(motorBPin2, LOW);
digitalWrite(ledPin, HIGH);

}
/* If right is pressed, turn the car to the right. */
else if (GamePad.isRightPressed() || x < -6)
{
analogWrite(motorASpeedPin, 255);
analogWrite(motorBSpeedPin, 255);
digitalWrite(motorAPin1, LOW);
digitalWrite(motorAPin2, HIGH);
digitalWrite(motorBPin1, HIGH);
digitalWrite(motorBPin2, LOW);
digitalWrite(ledPin, HIGH);

}
/* If left is pressed, turn the car to the left. */
else if (GamePad.isLeftPressed()|| x > 6)
{
analogWrite(motorASpeedPin, 255);
analogWrite(motorBSpeedPin, 255);
digitalWrite(motorAPin1, HIGH);
digitalWrite(motorAPin2, LOW);
digitalWrite(motorBPin1, LOW);
digitalWrite(motorBPin2, HIGH);
digitalWrite(ledPin, HIGH);

}
/* If nothing is pressed stop all motors. */
else
{
analogWrite(motorASpeedPin, 0);
analogWrite(motorBSpeedPin, 0);
digitalWrite(ledPin, LOW);
}

}
4) Arduino Automatic Room Light Controller with
Bidirectional Visitor

COMPONENTS AND SUPPLIES


Arduino UNO & Genuino UNO × 1
Relay (generic)
× 1

Resistor 100 ohm


× 1

Infrared Module
× 1

Adafruit Standard LCD - 16x2


White on Blue
× 1

General Purpose Transistor NPN


× 1

Breadboard (generic)
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

The project of “Digital visitor counter” is based on the


interfacing of some components such as sensors,
motors etc. with Arduino microcontroller. This
counter can count people in both directions. This
circuit can be used to count the number of persons
entering a hall/mall/home/office in the entrance gate
and it can count the number of persons leaving the hall
by decrementing the count at the same gate or an exit
gate, and that depends upon sensor placement in the
mall/hall. It can also be used at gates of parking areas
and other public places.
This project is divided into four parts: sensors,
controller, counter display and gate. The sensor would
observe an interruption and provide an input to the
controller which would run the counter increment or
decrement depending on the entering or exiting of
people. And counting is displayed on a 16x2 LCD
through the controller.
SCHEMATICS
CODE

#include<LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8);
#define in 14
#define out 19
#define relay 2
int count=0;
void IN()
{
count++;
if(count>=10)
{
count=10;
}
lcd.clear();
lcd.print("Person In Room:");
lcd.setCursor(0,1);
lcd.print(count);
delay(1000);
}
void OUT()
{
count--;
if(count<=0)
{
count=0;
}
lcd.clear();
lcd.print("Person In Room:");
lcd.setCursor(0,1);
lcd.print(count);
delay(1000);
}
void setup()
{
lcd.begin(16,2);
lcd.print("Visitor Counter");
delay(2000);
pinMode(in, INPUT);
pinMode(out, INPUT);
pinMode(relay, OUTPUT);
lcd.clear();
lcd.print("Person In Room:");
lcd.setCursor(0,1);
lcd.print(count);
}
void loop()
{

if(digitalRead(in))
IN();
if(digitalRead(out))
OUT();

if(count<=0)
{
lcd.clear();
digitalWrite(relay, LOW);
lcd.clear();
lcd.print("Nobody In Room");
lcd.setCursor(0,1);
lcd.print("Light Is Off");
delay(200);
}
else
digitalWrite(relay, HIGH);

5) Arduino a Neonate Incubator Approach


COMPONENTS AND SUPPLIES

Arduino Nano R3
× 1

ABOUT THIS PROJECT

This project is an aproach to understand how neonate


incubator works. !!WARNING!! IT IS NOT
SUPOUSED TO TAKE CARE OF ANY KIND OF
LIFE, the purpose here is to understand the basics and
get your project as better as possible, and of course
have fun with it!!
This was made to represent the idea of low cost
medical devices for a diploma work.
The main goal of this incubator is to mantain the
temperature between a max and min temperature
range, this temperature range can be managed with a
5-button control. The airflow is created with help of
two fans that keep air flowing (two fans works at
small velocity but one of them has an increased
velocity switch in case of overwarming airflow), a
ceramic warmer, a servo motor to open and close a
gate that lets overwarmed air to flow outside the
system, temperature and humidity sensors, a power
supply and of course, our good Arduino Nano.
An upside view of the system
Here is the ceramic warmer, some sensors and the
servo controlled gate
Here you can see the place in which the air is warmed,
a Lm35 temperature sensor is in the top of the box
This project will be divided in several small projects
in order to explain how to build each specific part that
need special attention as the power controller and the
button controller.

SCHEMATICS

Simplified diagram
This diagram content the following:
1. 220V cable
2. Power source 220v to 24V @ 4A
3. Arduino Nano
4. I2C 20x4 LCD
5. Power controller for fans and warmer
6. 5-button control
7. Ceramic warmer
8. Lm 35 temperature sensor
9. DHT22 humidity and temperature sensor
10. 12V computer fan
11. Small servo motor.
12. Big plastic box
Arduino diagram
The Arduino connections to peripherals.
Power management
The two independent lines were made experimentally
to check if the helped to avoid some noises, but they
did not :) So you can use just one.

Amplification stages and voltage follower


Voltage follower is used to have better signal from
thermistors and the OpAmps to expand the Lm35
readable range in Arduino
5-button module
Here is a simple 5-button controller
Power control of fans and ceramic warmer
CODE

#include <LCD.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SimpleDHT.h>
#include "RTClib.h"
#include <dht.h>
#include <Servo.h>

Servo myservo;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //Set the


LCD I2C address

//Digitals
const int pin1DHT22 = 2; //Sensor humedad 1
const int Warmer = 3; //Relay 3
const int Fan_1 = 6; //Relay 6 // Fan High
const int buzzer = 4; //Piezo sounder
const int button1 = 9;
const int button2 = 10;
const int button3 = 11;
const int button4 = 12;
const int button5 = 13;

//Analogs
const int inPinTh_1 = A1; //Termistor 2
const int tempPin_1 = A2; //lm35_1
const int tempPin_2 = A3; //lm35_2

SimpleDHT22 dht22_1;
RTC_DS1307 RTC;
int temp_1, temp_2, DHT22Temp_1;
int errorSense_1, errorSense_2, count_1, count_2, count_3 = 0;

int menuScreen, menuScreenUseAlarm, menuScreenMode,


menuScreenTempAlarm, menuScreenTemp, menuScreenHumid, mode,
modeAlarm, manualSettings = 0;
bool back, next, select, up, down = 0;

float Temp1_Neonate, Temp2_Neonate, averageTemp_Neonate, lm35_1,


lm35_2, coefWarmer, midleRangeTemp = 0;
int pursuedHigherT = 373;
int pursuedLowerT = 365;

float upperTemp = 35;


float lowerTemp = 34;
float lowerTempComp = 0;

float upperTempAlarm = 37.5;


float lowerTempAlarm = 36.5;
float lowerTempCompAlarm = 0;

unsigned long currentMillis;


unsigned long previousMillis = 0; // last time update
long interval = 1000; // interval at which to do something (milliseconds)

unsigned long currentMillis_1;


unsigned long previousMillis_1 = 0; // last time update
long interval_1 = 2000; // interval at which to do something (milliseconds)

void setup()
{
myservo.attach(1);
myservo.write(122); //Para flujo sobrecalentado
delay(250);
myservo.write(70); //Flujo normal
delay(250);
myservo.write(122);
delay(250);
myservo.write(70);
Wire.begin();
RTC.begin();
pinMode(Fan_1, OUTPUT);
pinMode(Warmer, OUTPUT);
pinMode(back, INPUT);
pinMode(next, INPUT);
pinMode(select, INPUT);
pinMode(up, INPUT);
pinMode(down, INPUT);

pinMode(buzzer, OUTPUT);
digitalWrite(buzzer, LOW);

digitalWrite(Fan_1, LOW);
digitalWrite(Warmer, LOW);

lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines and turn on
backlight
lcd.backlight();
menuScreen_0();
menuScreen_1();
RTC.adjust(DateTime(__DATE__, __TIME__));
// Check to see if the RTC is keeping time. If it is, load the time from your
computer.
if (! RTC.isrunning()) {
lcd.print("Change clock battery");
// This will reflect the time that your sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
}

void loop()
{
currentMillis = millis();
buttonState();

switch (menuScreen) {
case 0:
menuScreen_UseAlarm();
break;
case 1:
menuScreen_SetAlarm();
break;
case 2:
menuScreen_Mode();
break;
case 3:
Screen_Auto_intro();
break;
case 4:
menuScreen_Temp();
break;
case 5:
Alarms();
currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
Screen_Auto();
}
break;
case 6:
Alarms();
currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
Screen_Manual();
}
break;
}

void mainScreen()
{
currentMillis_1 = millis();

lcd.setCursor(0, 0);
lcd.print("Baby T "); lcd.print(averageTemp(), 1); lcd.print((char)223);
//lcd.print("C");
lcd.setCursor(13, 0);
lcd.print("WarmerT");
lcd.setCursor(0, 1);
lcd.print("Case T "); lcd.print(templm35_1(), 1); lcd.print((char)223); //
Temp case lm35 1
lcd.setCursor(14, 1);
lcd.print(templm35_2(), 1); lcd.print((char)223); // Temp warmer lm35 2
lcd.setCursor(0, 2);
lcd.print("Cham T ");
if (currentMillis_1 - previousMillis_1 > interval_1) { // Importante para dar
ciclo de espera a los sensores de humidificacion
previousMillis_1 = currentMillis_1; lcd.print(DHT22TempRead_1(), 1);
lcd.print((char)223);
}
lcd.setCursor(0, 3);
lcd.print("Man. mode");
RelojParaPantallaSerial();

void RelojParaPantallaSerial()
{
DateTime now = RTC.now();
lcd.setCursor(12, 3);
if (now.hour() < 10 ) {
lcd.print("0");
lcd.print(now.hour(), DEC);
}
else {
lcd.print(now.hour(), DEC);
}
lcd.print(':');
if (now.minute() < 10) {
lcd.print("0");
lcd.print(now.minute(), DEC);
}
else {
lcd.print(now.minute(), DEC);
}
lcd.print(':');
if (now.second() < 10) {
lcd.print("0");
lcd.print(now.second());
}
else {
lcd.print(now.second(), DEC);
}
}

void DHT22Sensor_1() // DHT22 sampling rate is 0.5HZ.


{
count_1 ++;
if (count_1 > 1) { //Sets counting of 2 seconds
count_1 = 0;
byte temperature_1 = 0;
byte humidity_1 = 0;
int err_1 = dht22_1.read(pin1DHT22, &temperature_1, &humidity_1,
NULL);
if (err_1 != SimpleDHTErrSuccess) {
errorSense_1 ++;
if (errorSense_1 > 2) { // Here we set the number of errors allowed untill
display an error
lcd.setCursor(10, 2);
lcd.print("Error"); lcd.print(err_1); delay(1000);
return;
}
return;
}
errorSense_1 = 0; // Reset the counter if the errors in a row are not
higher than errors allowed untill display an error
DHT22Temp_1 = ((int)temperature_1);
count_1 = 0;
}
}
int DHT22TempRead_1()
{
DHT22Sensor_1();
return DHT22Temp_1;
}

float temperature_Neonate() // CREAR ERROR DE TEMP


{
float val1 = 0;
for (int i = 0; i < 5; i++) {
val1 = val1 + analogRead(inPinTh_1);
delay(2);
}
Temp2_Neonate = val1 / 5;
return Temp2_Neonate;
}

float templm35_1()
{
float val2 = 0;
for (int i = 0; i < 5; i++) {
val2 = val2 + analogRead(tempPin_1);
delay(2);
}
lm35_1 = val2 / 5;
lm35_1 = mapf(lm35_1, 284.5, 323, 30, 37);
return lm35_1;
}

float templm35_2()
{
float val3 = 0;
for (int i = 0; i < 5; i++) {
val3 = val3 + analogRead(tempPin_2);
delay(2);
}
lm35_2 = val3 / 5;
lm35_2 = mapf(lm35_2, 284.5, 323, 30, 37);
return lm35_2;
}

double mapf(double x, double in_min, double in_max, double out_min,


double out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

float averageTemp() // Average was with two thermometers


{
averageTemp_Neonate = temperature_Neonate();
averageTemp_Neonate = mapf(averageTemp_Neonate, 284.5, 323, 30, 37);
return averageTemp_Neonate;
}

int int_templm35_1()
{
int intlm35_1 = templm35_1();
return intlm35_1;
}

int int_tempcase()
{
int int_templm35_1_0 = templm35_1() * 10;
return int_templm35_1_0;
}

int int_templm35_2()
{
int intlm35_2 = templm35_2();
return intlm35_2;
}

int int_templm35_2_0()
{
int int_templm35_2_0 = templm35_2() * 10;
return int_templm35_2_0;
}
////////////////////////////////////////////////////

void menuScreen_0 ()
{
lcd.setCursor(0, 1);
lcd.print(" The Baby Warmer.");
delay(1000);
lcd.setCursor(0, 3);
lcd.print("Welcome!");
delay(500);
lcd.setCursor(15, 3);
lcd.print("V 1.3");
delay(1000);
lcd.clear();
}

void menuScreen_1()
{
lcd.setCursor(0, 0);
lcd.print("The following menu");
lcd.setCursor(0, 1);
lcd.print("will help you to set");
lcd.setCursor(0, 2);
lcd.print("the incubator system");
delay(3000);
lcd.clear();
}

void menuScreen_UseAlarm()
{
switch (menuScreenUseAlarm) {
case 0:
lcd.setCursor(0, 0);
lcd.print("Activate neonate");
lcd.setCursor(0, 1);
lcd.print("temp. alarm?");
if (modeAlarm == 0) {
lcd.setCursor(0, 2);
lcd.print("->");
}
else if (modeAlarm == 1) {
lcd.setCursor(0, 3);
lcd.print("->");
}
lcd.setCursor(2, 2);
lcd.print("No");
lcd.setCursor(2, 3);
lcd.print("Yes");
if (back) {
back = 0;
}
else if (next) {
if (modeAlarm == 0) {
menuScreen = 2;
}
else if (modeAlarm == 1) {
menuScreen = 1;
}
lcd.clear();
delay(500);
next = 0;
}
else if (select) {
if (modeAlarm == 0) {
menuScreen = 2;
}
else if (modeAlarm == 1) {
menuScreen = 1;
}
lcd.clear();
delay(500);
select = 0;
}
else if (up) {
modeAlarm = modeAlarm - 1;
if (modeAlarm < 0) {
modeAlarm = 1;
}
delay(100);
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
up = 0;
}
else if (down) {
modeAlarm = modeAlarm + 1;
if (modeAlarm > 1) {
modeAlarm = 0;
}
delay(100);
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
down = 0;
}
break;
}
}

void menuScreen_SetAlarm()
{
switch (menuScreenTempAlarm) {
case 0:
lcd.setCursor(0, 0);
lcd.print("Set the upper range");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(3, 1);
lcd.print(upperTempAlarm, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Press select to");
lcd.setCursor(0, 3);
lcd.print("continue...");
if (back) {
back = 0;
lcd.clear();
delay(500);
menuScreen = 0;
}
else if (next) {
lowerTempCompAlarm = upperTempAlarm - 0.5;
lowerTempAlarm = upperTempAlarm - 0.5;
menuScreenTempAlarm = 1;
lcd.clear();
delay(500);
next = 0;
}
else if (select) {
lowerTempCompAlarm = upperTempAlarm - 0.5;
lowerTempAlarm = upperTempAlarm - 0.5;
menuScreenTempAlarm = 1;
lcd.clear();
delay(500);
select = 0;
}
else if (up) {
if (int_upperTempAlarm() >= 375) {
upperTempAlarm = 37.5;
lcd.setCursor(9, 1);
lcd.print(" MAX TEMP");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
upperTempAlarm = upperTempAlarm + 0.1;
lcd.setCursor(3, 1);
lcd.print(upperTempAlarm, 1);
up = 0;
}
else if (down) {
if (int_upperTempAlarm() <= 320) {
upperTempAlarm = 32;
lcd.setCursor(10, 1);
lcd.print("MIN RANGE");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
upperTempAlarm = upperTempAlarm - 0.1;
lcd.setCursor(3, 1);
lcd.print(upperTempAlarm, 1);
down = 0;
}
break;

case 1:
lcd.setCursor(0, 0);
lcd.print("Set the lower range");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(3, 1);
lcd.print(lowerTempAlarm, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Press select to");
lcd.setCursor(0, 3);
lcd.print("continue...");

if (back) {
menuScreenTempAlarm = 0;
lcd.clear();
delay(200);
back = 0;
}
else if (next) {
menuScreenTempAlarm = 2;
next = 0;
lcd.clear();
delay(500);
}
else if (select) {
menuScreenTempAlarm = 2;
select = 0;
lcd.clear();
delay(500);
}
else if (up) {
if (int_lowerTempAlarm() >= (int_upperTempAlarm() - 5)) {
lowerTempAlarm = lowerTempCompAlarm;
lcd.setCursor(9, 1);
lcd.print(" MIN RANGE");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
lowerTempAlarm = lowerTempAlarm + 0.1;
lcd.setCursor(3, 1);
lcd.print(lowerTempAlarm, 1);
up = 0;
}
else if (down) {
if (int_lowerTempAlarm() <= 280) {
lowerTempAlarm = 28;
lcd.setCursor(10, 1);
lcd.print("MIN TEMP");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
lowerTempAlarm = lowerTempAlarm - 0.1;
lcd.setCursor(3, 1);
lcd.print(lowerTempAlarm, 1);
down = 0;
}
break;

case 2:
lcd.setCursor(0, 0);
lcd.print("Upper limit: ");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(3, 1);
lcd.print(upperTempAlarm, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Lower limit:");
lcd.setCursor(0, 3);
lcd.print("T=");
lcd.setCursor(3, 3);
lcd.print(lowerTempAlarm, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print(" Continue?");
if (back) {
menuScreenTempAlarm = 1;
lcd.clear();
delay(200);
back = 0;
}
else if (next) {
menuScreen = 2;
next = 0;
lcd.clear();
delay(500);
}
else if (select) {
menuScreen = 2;
select = 0;
lcd.clear();
delay(500);
}
else if (up) {
up = 0;
}
else if (down) {
down = 0;
}
}

void menuScreen_Mode()
{
switch (menuScreenMode) {
case 0:
lcd.setCursor(0, 0);
lcd.print("Select the mode:");

if (mode == 0) {
lcd.setCursor(0, 2);
lcd.print("->");
}
else if (mode == 1) {
lcd.setCursor(0, 3);
lcd.print("->");
}
lcd.setCursor(2, 2);
lcd.print("Skin mode aut.");
lcd.setCursor(2, 3);
lcd.print("Temp setting man.");
if (back) {
back = 0;
lcd.clear();
delay(500);
menuScreenTempAlarm = 0;
menuScreen = 0;
}
else if (next) {
if (mode == 0) {
menuScreen = 3;
}
else if (mode == 1) {
menuScreen = 4;
}
lcd.clear();
delay(500);
next = 0;
}
else if (select) {
if (mode == 0) {
menuScreen = 3;
}
else if (mode == 1) {
menuScreen = 4;
}
lcd.clear();
delay(500);
select = 0;
}
else if (up) {
mode = mode - 1;
if (mode < 0) {
mode = 1;
}
delay(100);
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
up = 0;
}
else if (down) {
mode = mode + 1;
if (mode > 1) {
mode = 0;
}
delay(100);
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
down = 0;
}
break;
}
}

void Screen_Auto_intro()
{
lcd.setCursor(0, 0);
lcd.print("This mode will try");
lcd.setCursor(0, 1);
lcd.print("to stabilize the");
lcd.setCursor(0, 2);
lcd.print("neonate temperature");
lcd.setCursor(0, 3);
lcd.print("between 36.5 & 37.3");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("The supervision of");
lcd.setCursor(0, 1);
lcd.print("the neonate is ");
lcd.setCursor(0, 2);
lcd.print("mandatory at small");
lcd.setCursor(0, 3);
lcd.print("lapses. 5~10 mins");
delay(3000);
lcd.clear();
menuScreen = 5;
}

void menuScreen_Temp()
{

switch (menuScreenTemp) {
case 0:
lcd.setCursor(0, 0);
lcd.print("Set the upper range");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(3, 1);
lcd.print(upperTemp, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Press select to");
lcd.setCursor(0, 3);
lcd.print("continue...");
if (back) {
back = 0;
menuScreen = 0;
}
else if (next) {
lowerTempComp = upperTemp - 1;
lowerTemp = upperTemp - 1;
menuScreenTemp = 1;
lcd.clear();
delay(500);
next = 0;
}
else if (select) {
lowerTempComp = upperTemp - 1;
lowerTemp = upperTemp - 1;
menuScreenTemp = 1;
lcd.clear();
delay(500);
select = 0;
}
else if (up) {
if (int_upperTemp() >= 370) {
upperTemp = 37;
lcd.setCursor(9, 1);
lcd.print(" MAX TEMP");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
upperTemp = upperTemp + 0.1;
lcd.setCursor(3, 1);
lcd.print(upperTemp, 1);
up = 0;
}
else if (down) {
if (int_upperTemp() <= 310) {
upperTemp = 31;
lcd.setCursor(10, 1);
lcd.print("MIN RANGE");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
upperTemp = upperTemp - 0.1;
lcd.setCursor(3, 1);
lcd.print(upperTemp, 1);
down = 0;
}
break;

case 1:
lcd.setCursor(0, 0);
lcd.print("Set the lower range");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(3, 1);
lcd.print(lowerTemp, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Press select to");
lcd.setCursor(0, 3);
lcd.print("continue...");
if (back) {
menuScreenTemp = 0;
lcd.clear();
delay(200);
back = 0;
}
else if (next) {
menuScreenTemp = 2;
next = 0;
lcd.clear();
delay(500);
}
else if (select) {
menuScreenTemp = 2;
select = 0;
lcd.clear();
delay(500);
}
else if (up) {
if (int_lowerTemp() >= (int_upperTemp() - 10)) {
lowerTemp = lowerTempComp;
lcd.setCursor(9, 1);
lcd.print(" MIN RANGE");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
lowerTemp = lowerTemp + 0.1;
lcd.setCursor(3, 1);
lcd.print(lowerTemp, 1);
up = 0;
}
else if (down) {
if (int_lowerTemp() <= 300) {
lowerTemp = 30;
lcd.setCursor(10, 1);
lcd.print("MIN TEMP");
delay(1000);
lcd.setCursor(9, 1);
lcd.print(" ");
return;
}
lowerTemp = lowerTemp - 0.1;
lcd.setCursor(3, 1);
lcd.print(lowerTemp, 1);
down = 0;
}
break;

case 2:
lcd.setCursor(0, 0);
lcd.print("Upper limit: ");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(3, 1);
lcd.print(upperTemp, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Lower limit:");
lcd.setCursor(0, 3);
lcd.print("T=");
lcd.setCursor(3, 3);
lcd.print(lowerTemp, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print(" Continue?");
if (back) {
menuScreenTemp = 1;
lcd.clear();
delay(200);
back = 0;
}
else if (next) {
menuScreen = 6;
next = 0;
lcd.clear();
delay(500);
}
else if (select) {
menuScreen = 6;
select = 0;
lcd.clear();
delay(500);
}
else if (up) {
up = 0;
}
else if (down) {
down = 0;
}
}

void Screen_Auto() {
Screen_Auto_S();
warmerParameters_Auto();
}

void Screen_Auto_S()
{
currentMillis_1 = millis();

lcd.setCursor(0, 0);
lcd.print("Baby T "); lcd.print(averageTemp(), 1); lcd.print((char)223);
//lcd.print("C");
lcd.setCursor(13, 0);
lcd.print("WarmerT");
lcd.setCursor(0, 1);
lcd.print("Case T "); lcd.print(templm35_1(), 1); lcd.print((char)223); //
Temp case lm35 1
lcd.setCursor(14, 1);
lcd.print(templm35_2(), 1); lcd.print((char)223); // Temp warmer lm35 2
lcd.setCursor(0, 2);
lcd.print("Purs Baby T ");
lcd.print("37.3"); lcd.print((char)223);
lcd.setCursor(0, 3);
lcd.print("Aut. mode");
RelojParaPantallaSerial();

void Screen_Manual()
{
mainScreen();
warmerParameters_Manual();
}

void warmerParameters_Auto()
{
switch (manualSettings) {
case 0:
if (int_tempcase() <= int_lowerTemp()) {
digitalWrite(Warmer, HIGH);
}
else if (int_tempcase() > int_lowerTemp()) {
manualSettings++;
digitalWrite(Warmer, LOW);
}

case 1:
if (int_tempcase() <= pursuedLowerT) {
digitalWrite(Warmer, HIGH);
delay(400);
digitalWrite(Warmer, LOW);
delay(300);
}
else if (int_tempcase() >= pursuedHigherT) {
digitalWrite(Warmer, LOW);
digitalWrite(Fan_1, HIGH);
myservo.write(122); //Para flujo sobrecalentado
delay(2500); //Variable de tiempo de
enfriamiento, a mas tiempo, mas frio
digitalWrite(Fan_1, LOW);
myservo.write(70);
delay(1000);
}
}
}

void warmerParameters_Manual()
{
switch (manualSettings) {
case 0:
if (int_tempcase() <= int_lowerTemp()) {
digitalWrite(Warmer, HIGH);

}
else if (int_tempcase() > int_lowerTemp()) {
manualSettings++;
digitalWrite(Warmer, LOW);
}

case 1:
if (int_tempcase() <= int_upperTemp()) {
digitalWrite(Warmer, HIGH);
delay(400);
digitalWrite(Warmer, LOW);
delay(300);
}
else if (int_tempcase() >= int_upperTemp()) {
digitalWrite(Warmer, LOW);
digitalWrite(Fan_1, HIGH);
myservo.write(122); //Para flujo sobrecalentado
delay(2500); //Variable de tiempo de
enfriamiento, a mas tiempo, mas frio
digitalWrite(Fan_1, LOW);
myservo.write(70);
delay(1000);
}
}
}

void Alarms()
{
if (modeAlarm == 1)
{
if (averageTemp() < lowerTempAlarm || averageTemp() >
upperTempAlarm)
{
digitalWrite(buzzer, HIGH);
delay(150);
digitalWrite(buzzer, LOW);
delay(100);

}
}
else {
digitalWrite(buzzer, LOW);
}
}

void buttonState()
{
back = digitalRead(button1);
next = digitalRead(button2);
select = digitalRead(button3);
up = digitalRead(button4);
down = digitalRead(button5);

if (back == HIGH) {
delay(150);
}

if (next == HIGH) {
delay(150);
}
if (select == HIGH) {
delay(150);
}

if (up == HIGH) {
delay(150);
}

if (down == HIGH) {
delay(150);
}
}

int int_upperTemp()
{
int int_upperTemp = upperTemp * 10;
return int_upperTemp;
}

int int_lowerTemp()
{
int int_lowerTemp = lowerTemp * 10;
return int_lowerTemp;
}

int int_midleRangeTemp()
{
int int_midleRangeTemp = midleRangeTemp * 10;
return int_midleRangeTemp;
}

int int_coefWarmer()
{
int int_coefWarmer = coefWarmer * 10;
return int_coefWarmer;
}

int int_upperTempAlarm()
{
int int_upperTempAlarm = upperTempAlarm * 10;
return int_upperTempAlarm;
}

int int_lowerTempAlarm()
{
int int_lowerTempAlarm = lowerTempAlarm * 10;
return int_lowerTempAlarm;
}
6) Arduino Customizable Geiger Muller Counter
COMPONENTS AND SUPPLIES

Arduino UNO & Genuino UNO


Can be any arduino device, × 1
does not have to be UNO

DC-DC 1.5-3V to 300-400V × 1


380V High Voltage Boost Step-
up Voltage Inverter Module
Ideal final voltage is 400V, but
can be from 350-450V (the
power range of the GM tube).
STS-5 Geiger Muller Tube
I found mine on ebay (less
expensive). Be aware that you
× 1
will likely have to buy from the
Ukraine and it won't arrive for
probably 2-3 weeks.
SunFounder IIC I2C TWI Serial
2004 20x4 LCD Module Shield
for Arduino Uno Mega2560
Flexibility on the unit. I used
× 1
this LED display as had fewer
wires involved going into it.
Get a 20x4 and you will be
fine.
NECESSARY TOOLS AND MACHINES
Soldering iron (generic)
Needed to create device matching to
circuit board. Also required to solder the
capacitor to the voltage transformer.
Breadboard, 270 Pin
My final project employed a solderable
self-assembled circuit board, but if one is
interested in a less permanent project, I
found this to work as well.

ABOUT THIS PROJECT

AS NOTED BY THE WORK OF ADNOVEA, THIS


DEVICE USES HIGH VOLTAGES (400 V) THAT
ARE DANGEROUS. WHILE CURRENTS ARE
LOW, ANY AMOUNT OF CURRENT OR
VOLTAGE INTRODUCED TO THE HUMAN BODY
CAN INDUCE AN ARRHYTHMIA IN THE HEART
THAT CAN STOP IT AND LEAD TO DEATH.
PEOPLE WHO BUILD THIS PRODUCT SHOULD
HAVE SOME EXPERIENCE WITH ELECTRONICS
AND BE EXTREMELY MINDFUL OF
APPROPRIATE SAFETY PRECAUTIONS WHILE
USING THE HIGH VOLTAGE ASPECT OF THE
CIRCUIT.
My goal was to take the work of AdNovea and create
a Geiger Muller counter that I had more freedom to
program as I desired (the AdNovea work employed
scripts that I was unable to find the appropriate
program to modify). This would permit a user to both
better understand the physics of the tube, but also
create such a device that meets their project
desires/needs.
For the project, I simplified the circuit diagram from
AdNovea to make something more for what I was
looking for: a personal counter that shows the counts,
but not getting too complicated with ethernet
connections and connection to national networks. I
experimented with Bluetooth modules and buzzers and
these can work with it, though I chose not to use them
as I wanted more of a background radiation counter I
could refer to when I wanted.
The construction is very straight forward (refer to
circuit diagram). The only difficult aspects of this
project was obtaining some of the parts (the GM tube
and the high voltage converter). I purchased both of
these items for little money on Ebay, but both were
being sold from far away (the Ukraine and China
respectively) so it took 3-4 weeks to receive the items.
I started with assembling the circuit on a bread board
to best evaluate the circuit and where I could
manipulate it to my desires. I assembled it per
AdNovea's diagram, but left out the buzzer, ethernet
module, and resistor leading to the GM tube (I was not
getting sufficient current to the tube with that circuit
design that prevented it from working). I then soldered
it all onto a circuit board.

I have an Arduino uno cited here as what I used, but


you could probably save space in a container by using
a nano. I used electrical tape to attach the GM tube to
the circuit board to save space as well as to cover the
terminals on the voltage transformer to improve
safety. As I have limited equipment to play around and
drill holes with a plastic container to make something
pretty like what AdNovea had, I used the cardboard
box that I was given when I first purchased my
Arduino circuit kit.

I did cut a hole in the top of the box so the LED


display could fit snugly in there (and I further
reinforced this with tape).
I also cut a hole in the side of the box to permit a USB
cord to come in and power the device.
I attempted 9V batteries to start, but as expected, the
batteries did not last long. Finally I put additional
electric tape around the box/circuit board as needed at
points where the circuit may come in contact with the
cardboard to protect against fire and losing signal.
The program I have designed for my project takes the
counts collected by the GM tube every 30 seconds
multiplied by 2 to provide an estimated counts per
minute (measuring unit of GM tubes). I then used
metric system conversions to report uSv/hr that is a
more widely used reference measurement. As the
device continues to run through this code, I had it
report the average of the measurements that
progressively were collected along with the standard
error (SD / sqrt(n)). Statistically I chose standard error
as ultimately what is collected is a sample from the
mean background radiation levels making SE the more
appropriate measure. Unfortunately due to the
memory limitations of the Arduino, I was only able to
create an array of measurements of 100 items

SCHEMATICS
CODE

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
unsigned long counts; //variable for GM Tube events
unsigned long previousMillis; //variable for measuring time
float averageCPM;
float sdCPM;
int currentCPM;
float calcCPM;
LiquidCrystal_I2C lcd(0x27, 20, 4);
float CPMArray[100];

#define LOG_PERIOD 30000 // count rate (in milliseconds)

void setup() { //setup


counts = 0;
currentCPM = 0;
averageCPM = 0;
sdCPM = 0;
calcCPM = 0;
lcd.init();
lcd.backlight();
Serial.begin(9600);
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), impulse, FALLING); //define
external interrupts
}

void loop() { //main cycle


lcd.setCursor(0,2);
lcd.print("CPM Count: ");
lcd.print(counts);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > LOG_PERIOD) {
previousMillis = currentMillis;
CPMArray[currentCPM] = counts * 2;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("uSv/hr: ");
lcd.print(outputSieverts(CPMArray[currentCPM]));
counts = 0;
averageCPM = 0;
sdCPM = 0;
//calc avg and sd
for (int x=0;x<currentCPM+1;x++) {
averageCPM = averageCPM + CPMArray[x];
}
averageCPM = averageCPM / (currentCPM + 1);
for (int x=0;x<currentCPM+1;x++) {
sdCPM = sdCPM + sq(CPMArray[x] - averageCPM);
}
sdCPM = sqrt(sdCPM / currentCPM) / sqrt(currentCPM+1);

Serial.println("Avg: " + String(averageCPM) + " +/- " + String(sdCPM) + "


ArrayVal: " + String(CPMArray[currentCPM]));
currentCPM = currentCPM + 1;
displayAverageCPM();
}
}

void impulse() {
counts++;
}
void displayAverageCPM() {
lcd.setCursor(0,1);
lcd.print("Avg: ");
lcd.print(outputSieverts(averageCPM));
lcd.print("+/-");
lcd.print(outputSieverts(sdCPM));
}
float outputSieverts(float x) {
float y = x * 0.0057;
return y;
}
7) Arduino WKR1000 Weather Station
COMPONENTS AND SUPPLIES

Arduino MKR1000
× 1

Adafruit TSL2561 Luminosity


Sensor × 1

Adafruit BMP180 Barometric


Pressure/Temperature × 1

OLED display I2C


× 1

SparkFun Level Shifter Board


× 1

Sharp GP2Y1010AU0F
× 1

Soil Moisture Sensor × 1


Breadboard (generic)
× 1

Jumper wires (generic)


× 1
APPS AND ONLINE SERVICES
Arduino IDE

myDevices Cayenne

ABOUT THIS PROJECT


The OLED display shows the temperature, pressure and
dust. The Arduino MKR1000 is connected to the
Cayenne over MQTT.
Connecting the Arduino MKR1000 to Cayenne:
Add new: Device/Widget
Bring Your Own Thing
Add code to Username, Password and Client ID
Add code to SSID and Password from your Wi-Fi
Upload code to the Arduino MKR1000
Wait for board to connect
Add Widgets:
Add new: Device/Widget
Custom Widgets
Select a widget that you need
Enter the name of the widget
Select device, Virtual Pin, Pin number
Select Data, Unit, Icon
Add Widget

SCHEMATICS
CODE

#define CAYENNE_PRINT Serial // Comment this out to disable prints and


save space
#include <CayenneMQTTMKR1000.h>

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_TSL2561_U.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define BAROMETER_PIN V1
#define TEMPERATURE_PIN V2
#define LIGHT_PIN V3
#define DUST_PIN V4
#define MOISTURE_PIN V5

float temperature;
float pressure;
float voltage;
int moisture;

int measuringPin = A1;


int ledPin = 2;
const int timeMeasuring = 280;
const int timeStabilization = 40;
const int timeSleep = 9680;
float voltageAnalog = 0;
float voltageConversion = 0;
float dustiness = 0;
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10180);
const int address = TSL2561_ADDR_FLOAT;
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(address,
12345);

// WiFi network info.


char ssid[] = "SSID";
char wifiPassword[] = "Password";

// Cayenne authentication info. This should be obtained from the Cayenne


Dashboard.
char username[] = "Username";
char password[] = "Password";
char clientID[] = "ClientID";

unsigned long lastMillis = 0;

void setup()
{
Serial.begin(9600);
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
pinMode(ledPin,OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
if (!bmp.begin())
{
CAYENNE_LOG("No BMP sensor detected");
while (1);
}
if (!tsl.begin())
{
CAYENNE_LOG("No TSL2561 detected");
while (1);
}

tsl.enableAutoRange(true);
/* Changing the integration time gives you better sensor resolution (402ms
= 16-bit data) */
tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); /* fast
but low resolution */
// tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); /*
medium resolution and speed */
// tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS); /* 16-
bit data but slowest conversions */
}

void loop()
{
Cayenne.loop();

//Publish data every 10 seconds (10000 milliseconds). Change this value to


publish at a different interval.
if (millis() - lastMillis > 10000) {
lastMillis = millis();
//Write data to Cayenne here. This example just sends the current uptime in
milliseconds.
Cayenne.virtualWrite(0, lastMillis);

sensors_event_t event;
tsl.getEvent(&event);
bmp.getPressure(&pressure);
bmp.getTemperature(&temperature);

digitalWrite(ledPin,LOW);
delayMicroseconds(timeMeasuring);
voltageAnalog = analogRead(measuringPin);
delayMicroseconds(timeStabilization);
digitalWrite(ledPin,HIGH);
delayMicroseconds(timeSleep);

voltageConversion = voltageAnalog * 2 * (3,3 / 1024.0);


dustiness = (0.17 * voltageConversion - 0.1)*1000;

moisture = analogRead(A2);
Cayenne.luxWrite(LIGHT_PIN, event.light);
Cayenne.hectoPascalWrite(BAROMETER_PIN, pressure);
Cayenne.celsiusWrite(TEMPERATURE_PIN, temperature);
Cayenne.virtualWrite(DUST_PIN, dustiness);
Cayenne.virtualWrite(MOISTURE_PIN, map(moisture, 1023, 0, 0, 100));

}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println(temperature);
display.setCursor(40, 0);
display.println("C");
display.setCursor(0, 10);
display.println(pressure);
display.setCursor(55, 10);
display.println("Pa");
display.setCursor(0, 20);
display.println(dustiness);
display.setCursor(45, 20);
display.println("ug/m3");
display.display();

}
8) Arduino Due TIC TAC TOE with Touchscreen

COMPONENTS AND SUPPLIES


Arduino Due
× 1

2,8 zoll TFT LCD with × 1


touchscreen
Jumper wires (generic)
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

About
Hello, I want to share my work on the project from
nickthegreek82: arduino-touch-tic-tac-toe-game.
You need:
the Adafruit Library
the GFX Library
and the URTouch Library
Wiring
The wiring is as following for the touch-screen:
Touch -> Arduino Due
T_IRQ -> 22
T_DO -> 24
T_DIN -> 26
T_CS -> 28
T_CLK -> 30
For the display:
Display -> Arduino Due
SDO -> A.25
LED -> 3.3V
SCK -> A.27
SDI -> A.26
DC -> 9
RESET -> 8
CS -> 10
GND -> GND
VCC -> 3.3V

SCHEMATICS
CODE

/////////////////////////////////////////////
// 2.8" TOUCH SCREEN TIC TAC TOE //
// //
// //
// //
// //
/////////////////////////////////////////////

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <URTouch.h>

#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#define TOUCH_ORIENTATION LANDSCAPE

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

Adafruit_GFX_Button buttons[9];

URTouch myTouch(30, 28, 26, 24, 22);

char start[10] = {"Gamestart"};


char you[4] = {"YOU"};
char cpu[4] = {"CPU"};
char again[7] = {"Again?"};
int player;
int difficulty=8;
unsigned short int x,y,b; // position touch
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

int board[]={0,0,0,0,0,0,0,0,0};// holds position data 0 is blank, 1 human, 2


is computer
unsigned turn;

const unsigned char circle[]PROGMEM={


0b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x
0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x7,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xff,0x80,0x0,
0x0,0x0,0x0,0x0,0x3,0xff,0xff,0xf0,0x0,0x0,0x0,
0x0,0x0,0xf,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xfe,0x0,0x
0,0x0,0x0,0x0,0x7f,0xf0,0x3,0xff,0x80,0x0,0x0,0x0,0x0,0xff,0x80,0x0,0x7
f,0xc0,0x0,0x0,0x0,0x1,0xfe,0x0,0x0,0x1f,0xe0,0x0,0x0,
0x0,0x3,0xf8,0x0,0x0,0x7,0xf0,0x0,0x0,0x0,0x7,0xf0,0x0,0x0,0x3,0xf8,0x
0,0x0,0x0,0xf,0xe0,0x0,0x0,0x1,0xfc,0x0,0x0,0x0,0xf,0xc0,0x0,0x0,0x0,0x
fc,0x0,0x0,0x0,0x1f,0x80,0x0,0x0,0x0,0x7e,0x0,0x0,
0x0,0x3f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x3e,0x0,0x0,0x0,0x0,0x1f,0x
0,0x0,0x0,0x7e,0x0,0x0,0x0,0x0,0x1f,0x80,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,
0xf,0x80,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xf,0x80,0x0,
0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc
0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0
x3,0xc0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,
0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe
0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0
x3,0xe0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,
0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe
0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x3,0xc0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0
x7,0xc0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,
0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xf,0x8
0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xf,0x80,0x0,0x0,0x7e,0x0,0x0,0x0,0x0,0
x1f,0x80,0x0,0x0,0x3e,0x0,0x0,0x0,0x0,0x1f,0x0,0x0,
0x0,0x3f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x1f,0x80,0x0,0x0,0x0,0x7e,0
x0,0x0,0x0,0xf,0xc0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0xf,0xe0,0x0,0x0,0x1,0
xfc,0x0,0x0,0x0,0x7,0xf0,0x0,0x0,0x3,0xf8,0x0,0x0,
0x0,0x3,0xf8,0x0,0x0,0x7,0xf0,0x0,0x0,0x0,0x1,0xfe,0x0,0x0,0x1f,0xe0,0
x0,0x0,0x0,0x0,0xff,0x80,0x0,0x7f,0xc0,0x0,0x0,0x0,0x0,0x7f,0xf0,0x3,0x
ff,0x80,0x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0xf,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,0x3,0xff,0xff,0xf0,0x0,0x0
,0x0,0x0,0x0,0x0,0x7f,0xff,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xf8,0x0,0x
0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x
0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};
const unsigned char x_bitmap[]PROGMEM={
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x
0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x
0,0x0,0x3,0xff,0xff,0xc0,0x1,0xff,0xff,0xe0,0x0,
0x1,0xff,0xff,0xe0,0x1,0xff,0xff,0xc0,0x0,0x1,0xff,0xff,0xf0,0x3,0xff,0xff,
0xc0,0x0,0x0,0xff,0xff,0xf0,0x7,0xff,0xff,0x80,0x0,0x0,0xff,0xff,0xf8,0x7,
0xff,0xff,0x80,0x0,0x0,0x7f,0xff,0xf8,0xf,0xff,0xff,0x0,0x0,
0x0,0x3f,0xff,0xfc,0xf,0xff,0xfe,0x0,0x0,0x0,0x3f,0xff,0xfe,0x1f,0xff,0xfe,
0x0,0x0,0x0,0x1f,0xff,0xfe,0x1f,0xff,0xfc,0x0,0x0,0x0,0x1f,0xff,0xff,0x3f,
0xff,0xfc,0x0,0x0,0x0,0xf,0xff,0xff,0x7f,0xff,0xf8,0x0,0x0,
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0x0,0x7,0xff,0xff,0xff,0xff,0xf0,0
x0,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,0x0,0x3,0xff,0xff,0xff,0xf
f,0xe0,0x0,0x0,0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0x80,
0x0,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,0x0,0x0,0x7f,0xff,0xff,0
xff,0x0,0x0,0x0,0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xfc,0x0,0
x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xf
c,0x0,0x0,0x0,0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,0x0,0x0,0x7f,0xff,0xff,0xff,0x0,0
x0,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,0x0,0x0,0xff,0xff,0xff,0xf
f,0x80,0x0,0x0,0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0
x0,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,0x0,0x7,0xff,0xff,0xff,0xf
f,0xf0,0x0,0x0,0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0x0,0x1f,0xff,0xff,0x7f,0xff,0xfc,
0x0,0x0,0x0,0x1f,0xff,0xfe,0x3f,0xff,0xfc,0x0,0x0,0x0,0x3f,0xff,0xfc,0x3f,
0xff,0xfe,0x0,0x0,0x0,0x3f,0xff,0xfc,0x1f,0xff,0xfe,0x0,0x0,
0x0,0x7f,0xff,0xf8,0x1f,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xf8,0xf,0xff,0xff,
0x80,0x0,0x0,0xff,0xff,0xf0,0x7,0xff,0xff,0x80,0x0,0x1,0xff,0xff,0xe0,0x7
,0xff,0xff,0xc0,0x0,0x1,0xff,0xff,0xe0,0x3,0xff,0xff,0xc0,0x0,
0x3,0xff,0xff,0xc0,0x3,0xff,0xff,0xe0,0x0,0x3,0xff,0xff,0xc0,0x1,0xff,0xff,
0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0
x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x
0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};

void setup()
{
myTouch.InitTouch();
myTouch.setPrecision(PREC_HI);
tft.begin();
tft.setRotation(3);
}

void loop()
{
int board[9] = {0,0,0,0,0,0,0,0,0};

drawStartScreen();
do{
myTouch.read();
x = myTouch.getX(); //Get touch point
y = myTouch.getY();
delay(100);
}while(!(buttons[0].contains(x,y)));

tft.fillScreen(BLACK);
//Draw white frame
tft.drawRect(0,0,320,240,WHITE);
//Print "Tic Tac Toe" Text
tft.setCursor(30,30);
tft.setTextColor(WHITE);
tft.setTextSize(4);
tft.print("Tic Tac Toe");
//Print "YouTube!" text
tft.setCursor(30,100);
tft.setTextColor(GREEN);
tft.setTextSize(4);
tft.print("Who begins");
//Create Red Button
// create buttons // x, y, w, h, outline, fill, text
buttons[0].initButton(&tft, 100,200,80,40,WHITE, RED, WHITE,
you, 2);
buttons[0].drawButton();
// create buttons // x, y, w, h, outline, fill, text
buttons[1].initButton(&tft, 200,200,80,40,WHITE, RED, WHITE,
cpu, 2);
buttons[1].drawButton();
b=1;
do{
myTouch.read();
x = myTouch.getX(); //Get touch point
y = myTouch.getY();
if (buttons[0].contains(x,y))
{
b=0;
player = 1;
tft.fillScreen(BLACK);
//Draw white frame
tft.drawRect(0,0,320,240,WHITE);
tft.setCursor(30,30);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Ok, you begin.");
delay(2000);
}
if(buttons[1].contains(x,y))
{
b=0;
player = 2;
tft.fillScreen(BLACK);
//Draw white frame
tft.drawRect(0,0,320,240,WHITE);
tft.setCursor(30,30);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Ok, CPU begins.");
delay(2000);
}
}while(b);

tft.fillScreen(BLACK);
tft.drawRect(0,0,319,240,WHITE);

drawVerticalLine(125);
drawVerticalLine(195);
drawHorizontalLine(80);
drawHorizontalLine(150);

for(turn = 0; turn < 9 && win(board) == 0; ++turn) {


if((turn+player) % 2 == 0)
computerMove(board);
else {
//draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
Serial.println("It's a draw.\n");
break;
case 1:
//draw(board);
Serial.println("You lose.\n");
break;
case -1:
Serial.println("You win!\n");
break;
}
do{}while(myTouch.dataAvailable()==false);
//x = map(tp.y, 930, 88, 0, 480);
//y = map(tp.x, 908, 125, 0, 320);
//delay(250);}
}
void drawHorizontalLine(int y)
{
int i=0;
for(i=0;i<7;i++)
{
tft.drawLine(60,y+i,270,y+i,WHITE);
}
}

void drawVerticalLine(int x)
{
int i=0;
for(i=0;i<7;i++)
{
tft.drawLine(x+i,20,x+i,220,WHITE);
}
}
void drawStartScreen()
{
tft.fillScreen(BLACK);

//Draw white frame


tft.drawRect(0,0,319,240,WHITE);

//Print "Tic Tac Toe" Text


tft.setCursor(30,100);
tft.setTextColor(WHITE);
tft.setTextSize(4);
tft.print("Tic Tac Toe");

//Print "YouTube!" text


tft.setCursor(80,30);
tft.setTextColor(GREEN);
tft.setTextSize(4);
tft.print("Arduino");

buttons[0].initButton(&tft, 160,200,200,40,WHITE, RED, WHITE, start, 2);


buttons[0].drawButton();

void drawCircle(int x, int y)


{
drawBitmap(x,y,circle,65,65,RED);
}

void drawX(int x, int y)


{
drawBitmap(x,y,x_bitmap,65,65,BLUE);
}
void drawBitmap(int16_t x, int16_t y,
const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {

int16_t i, j, byteWidth = (w + 7) / 8;
uint8_t byte;

for(j=0; j<h; j++) {


for(i=0; i<w; i++) {
if(i & 7) byte <<= 1;
else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8);
if(byte & 0x80) tft.drawPixel(x+i, y+j, color);
}
}
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1, 0);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
drawCpuMove(move);
delay(100);
}

void playerMove(int board[9]) {


int move = 0;
b = 1;
do{
if (myTouch.dataAvailable() == true)
{
myTouch.read();
x = myTouch.getX(); //Get touch point
y = myTouch.getY();

if((x>55 && x<125)&& (y>0 && y<80)) //0


{
if(board[0]==0)
{
move=0;
b=0;
}
}
else if((x>125 && x<195) && (y>0 && y<80)) //1
{
if(board[1]==0)
{
move=1;
b=0;
}
}
else if((x>195&&x<265)&& (y>0 && y<80)) //2
{
if(board[2]==0)
{
move=2;
b=0;
}
}

else if((x>55 && x<125)&& (y>80 && y<155)) //3


{
if(board[3]==0)
{
move=3;
b=0;
}
}

else if((x>125 && x<195)&& (y>80 && y<155)) //4


{
if(board[4]==0)
{
move=4;
b=0;
}
}

else if((x>195&&x<265)&& (y>80 && y<155)) //5


{
if(board[5]==0)
{
move=5;
b=0;
}
}

else if((x>55 && x<125)&& (y>155 && y<235)) //6


{
if(board[6]==0)
{
move=6;
b=0;
}
}

else if((x>125 && x<195)&& (y>155 && y<235)) //7


{
if(board[7]==0)
{
move=7;
b=0;
}
}

else if((x>195&&x<265)&& (y>155 && y<235)) //8


{
if(board[8]==0)
{
move=8;
b=0;
}
}

}
}while(b);
board[move] = -1;
drawPlayerMove(move);
delay(100);
}
int win(const int board[9]) {
//list of possible winning positions
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},
{0,4,8},{2,4,6}};
int winPos;
for(winPos = 0; winPos < 8; ++winPos) {
if(board[wins[winPos][0]] != 0 && board[wins[winPos][0]] ==
board[wins[winPos][1]] && board[wins[winPos][0]] ==
board[wins[winPos][2]])
return board[wins[winPos][2]];
}
return 0;
}

int minimax(int board[9], int player, int depth) {


//check the positions for players
int winner = win(board);
if(winner != 0) return winner*player;

int move = -1;


int score = -2;
int i;
for(i = 0; i < 9; ++i) {

if(board[i] == 0) {
board[i] = player;
int thisScore=0;
if (depth<difficulty){
thisScore = -minimax(board, player*-1,depth+1);
}

if(thisScore > score) {


score = thisScore;
move = i;
}
//choose the worst move for opponent
board[i] = 0;
}
}
if(move == -1) return 0;
return score;
}
void drawCpuMove(int move)
{
switch(move)
{
case 0: drawCircle(55,15); break;
case 1: drawCircle(130,15); break;
case 2: drawCircle(205,15); break;
case 3: drawCircle(55,85); break;
case 4: drawCircle(130,85); break;
case 5: drawCircle(205,85); break;
case 6: drawCircle(55,155); break;
case 7: drawCircle(130,155);break;
case 8: drawCircle(205,155);break;
}
}

void drawPlayerMove(int move)


{
switch(move)
{
case 0: drawX(55,15); break;
case 1: drawX(130,15); break;
case 2: drawX(205,15); break;
case 3: drawX(55,85); break;
case 4: drawX(130,85); break;
case 5: drawX(205,85); break;
case 6: drawX(55,155); break;
case 7: drawX(130,155);break;
case 8: drawX(205,155);break;
}
}
9) Oled Display with Arduino 101

COMPONENTS AND SUPPLIES

Arduino 101 & Genuino 101


× 1
OLED 128X64 × 1

Rotary potentiometer (generic)


× 1

Jumper wires (generic)


× 1

USB-A to B Cable
× 1

Breadboard (generic)
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

Months ago I bought my Arduino 101 and wanted to


connect my shields and modules that I used in Arduino
One, but there were always problems with the libraries
and there were many headaches. I was looking for
information on the internet and could not find my
answers.
Today I finally found the way to connect my OLED
screen of 0.96 inches with Arduino 101 and I want to
share my discovery with this tutorial, since it could help
many people with the same problem as me.
Materials
To do this tutorial, we need materials, in this case we
will use an Arduino 101, the OLED screen with the
model SSD1306 of resolution 128X64 pixels, cables, a
potentiometer and a protoboard.

Code
Then open Arduino IDE and copy and paste the next
code:
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_SW_I2C
u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /*
reset=*/ U8X8_PIN_NONE); // All Boards without
Reset of the Display
int a=0; //variable of value of analog read pin
char taco[4];//variable to send text to the oled display
void setup(void) {
u8g2.begin();// Oled display begins
}
void loop(void) {
a=analogRead(A0); //read potentiometer value
sprintf(taco,"%04d",a); //convert potentiometer value to
string
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_inr38_mf); // choose a
suitable font
u8g2.drawStr(0,60,taco); // write something to the
internal memory
u8g2.sendBuffer(); // transfer internal memory to
the display
delay(1000);
For everything to work we must download the library
u8g2.
After uploading the code, and having connected the
potentiometer to the Arduino plate, the value of the
potentiometer can be seen in the display, from 0 to 1023,
as shown below.
SCHEMATICS
CODE

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*
clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All
Boards without Reset of the Display

int a=0; //variable of value of analog read pin


char taco[4];//variable to send text to the oled display
void setup(void) {
u8g2.begin();// Oled display begins
}

void loop(void) {
a=analogRead(A0); //read potentiometer value
sprintf(taco,"%04d",a); //convert potentiometer value to string
u8g2.clearBuffer(); // clear the internal
memory
u8g2.setFont(u8g2_font_inr38_mf); // choose a suitable font
u8g2.drawStr(0,60,taco); // write something to the internal memory
u8g2.sendBuffer(); // transfer internal
memory to the display
delay(1000);
}

10) Arduino Ask the Magic 8 Ball


COMPONENTS AND SUPPLIES

Resistor 10k ohm


× 2

Resistor 221 ohm


× 2
SparkFun Pushbutton switch × 1
12mm

Rotary potentiometer (generic)


× 1

Arduino LCD Screen


× 1

Jumper wires (generic)


× 21

Arduino UNO & Genuino UNO


× 1

Breadboard (generic)
× 1

USB-A to Micro-USB Cable × 1


NECESSARY TOOLS AND MACHINES
Arduino Materia 101
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

The purpose of this project was to create a Magic 8


Ball - Arduino style. We were able to do so by
modifying the Crystal Ball project in the Arduino
starter kit. The goal was to create a micro controller
that generates 20 random responses to the user's
statement and then switches to another response when
a switch button is pressed.
Why
Magic 8 Balls are one of the many fortune telling toys
that are popular with children. It was originally
developed in 1950. It returns 20 different statements
like "It is certain" in response to questions that
individuals ask. Magic 8 Balls are unique because can
be used by anyone, not just a fortune teller.
How It Works
The LCD display originally shows "Ask the Magic 8
ball!". The user then asks a question and presses the
button switch. The display then shifts to one of the 20
responses and then displays "Ask another question!".
The user can continue pressing the switch until all of
their questions are answered.
How to Make It
Follow the Arduino Project 11 - Crystal Ball in the
Arduino starter kit in order to construct the initial
circuit. Replace the tilt sensor with a button switch
and add a 220 ohm resistor two spaces in front of the
button switch. Alter the code so that when the button
is pressed, the Magic 8 ball returns one of the 20
responses and then displays "Ask another question!".
This alteration includes removing the code about the
tilt sensor and replacing it with an if statement (if the
switch is being pressed then return the statement +
"Ask another question!"). Change the code to reflect
what you want the magic 8 ball's response to be.
During this step you can utilize the delay function to
keep a message on the LCD display for a certain
amount of time. In between each of the 20 cases make
sure to include a break to differentiate between each
case.

SCHEMATICS
CODE

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int switchPin = 6;
int switchState = 0;
//declaring the variable for the switch
int reply;
void setup() {
pinMode(0, INPUT);
//power source for switch
lcd.begin(16, 2);
pinMode(switchPin, INPUT);
lcd.print("Ask the Magic");
lcd.setCursor(0,1);
lcd.print("8 ball!");
//welcome message
}
void loop(){
switchState = digitalRead(switchPin);
{
if(switchState == HIGH){
//when the switch is pressed
reply = random(8);
//return a random case
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("");
lcd.setCursor(0,1);
switch(reply){
case 0:
lcd.begin(16, 2);
lcd.print("It is");
lcd.setCursor(0,1);
lcd.print("certain :)");
delay (2500);
//maintain the first message
lcd.clear();
//clear the first message
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
//print the second message
break;
//next case
case 1:
lcd.begin(16, 2);
lcd.print("As I see it,");
lcd.setCursor(0,1);
lcd.print("yes :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 2:
lcd.begin(16, 2);
lcd.print("Reply hazy");
lcd.setCursor(0,1);
lcd.print("try again :/");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 3:
lcd.begin(16, 2);
lcd.print("Don't count");
lcd.setCursor(0,1);
lcd.print("on it :(");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 4:
lcd.begin(16, 2);
lcd.print("It is");
lcd.setCursor(0,1);
lcd.print("decidedly so :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 5:
lcd.begin(16, 2);
lcd.print("Most");
lcd.setCursor(0,1);
lcd.print("likely :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 6:
lcd.begin(16, 2);
lcd.print("Ask again");
lcd.setCursor(0,1);
lcd.print("later :/");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 7:
lcd.begin(16, 2);
lcd.print("My reply is");
lcd.setCursor(0,1);
lcd.print("no :(");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 8:
lcd.begin(16, 2);
lcd.print("Without a");
lcd.setCursor(0,1);
lcd.print("doubt :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 9:
lcd.begin(16, 2);
lcd.print("Outlook good :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 10:
lcd.begin(16, 2);
lcd.print("Better not tell");
lcd.setCursor(0,1);
lcd.print("you now :/");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 11:
lcd.begin(16, 2);
lcd.print("My sources");
lcd.setCursor(0,1);
lcd.print("say no :(");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 12:
lcd.begin(16, 2);
lcd.print("Yes");
lcd.setCursor(0,1);
lcd.print("definitely :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 13:
lcd.begin(16, 2);
lcd.print("Yes :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 14:
lcd.begin(16, 2);
lcd.print("Cannot");
lcd.setCursor(0,1);
lcd.print("predict now :/");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 15:
lcd.begin(16, 2);
lcd.print("Outlook not");
lcd.setCursor(0,1);
lcd.print("so good :(");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 16:
lcd.begin(16, 2);
lcd.print("You may rely");
lcd.setCursor(0,1);
lcd.print("on it :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 17:
lcd.begin(16, 2);
lcd.print("Signs point");
lcd.setCursor(0,1);
lcd.print("to yes :)");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 18:
lcd.begin(16, 2);
lcd.print("Concentrate and");
lcd.setCursor(0,1);
lcd.print("ask again :/");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
case 19:
lcd.begin(16, 2);
lcd.print("Very");
lcd.setCursor(0,1);
lcd.print("doubtful :(");
delay (2500);
lcd.clear();
lcd.print("Ask another");
lcd.setCursor(0,1);
lcd.print("question!");
break;
}
}
}
}

11) Arduino Calculator


COMPONENTS AND SUPPLIES
Arduino UNO & Genuino UNO
× 1

RGB LCD Shield Kit, 16x2


Character Display
× 1
Jumper wires (generic) × 1

9V battery (generic)
× 1

Breadboard (generic)
× 1

ABOUT THIS PROJECT

At the end of this project you will know how to use


a 16x2 LCD and Keypad with Arduino and also how
easy it is to program for them using the readily available
libraries. You will also understand how to program your
Arduino for accomplishing a particular task.
Materials Required:
Arduino Uno (Any version will work)
16×2 LCD Display
4×4 Keypad

9V Battery
Breadboard and Connecting wires
D0
1st pin of the keyboard
D1
2nd pin of the keyboard
D2
3rd pin of the keyboard
D3
4th pin of the keyboard
D4
5th pin of the keyboard
D5
6th pin of the keyboard
D6
7th pin of the keyboard
D7
8th pin of the keyboard
D8
Register select pin of LCD (pin 4)
D9
Enable pin of LCD (pin 6)
D10
Data pin 4 (pin 11)
D11
Data pin 4 (pin 11)
D12
Data pin 4 (pin 11)
D13
Data pin 4 (pin 11)
+5V
Connected to Vdd pin of LCD (pin 2)
Ground
Connected to Vss, Vee and RW pin of LCD (pin 1, 3 and
5)
Some Arduino boards might show an error while
uploading program if there are anything connected to pin
0 and pin1, so if you experience any just remove the
keypad while uploading the program.
Once your connections are done your hardware will look
something like this below
SCHEMATICS
CODE

*
* Arduino Keypad calculator Program
*/

#include <LiquidCrystal.h> //Header file for LCD from


https://www.arduino.cc/en/Reference/LiquidCrystal
#include <Keypad.h> //Header file for Keypad from
https://github.com/Chris--A/Keypad

const byte ROWS = 4; // Four rows


const byte COLS = 4; // Three columns

// Define the Keymap


char keys[ROWS][COLS] = {

{'7','8','9','D'},

{'4','5','6','C'},

{'1','2','3','B'},

{'*','0','#','A'}

};

byte rowPins[ROWS] = { 0, 1, 2, 3 };// Connect keypad ROW0, ROW1,


ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 4, 5, 6, 7 }; // Connect keypad COL0, COL1 and
COL2 to these Arduino pins.
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS,
COLS ); // Create the Keypad

const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; //Pins to which


LCD is connected
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

long Num1,Num2,Number;
char key,action;
boolean result = false;

void setup() {
lcd.begin(16, 2); //We are using a 16*2 LCD display
lcd.print("DIY Calculator"); //Display a intro message
lcd.setCursor(0, 1); // set the cursor to column 0, line 1
lcd.print("-CircuitDigest"); //Display a intro message

delay(2000); //Wait for display to show info


lcd.clear(); //Then clean it
}

void loop() {

key = kpd.getKey(); //storing pressed key value in a char

if (key!=NO_KEY)
DetectButtons();

if (result==true)
CalculateResult();

DisplayResult();
}

void DetectButtons()
{
lcd.clear(); //Then clean it
if (key=='*') //If cancel Button is pressed
{Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;}

if (key == '1') //If Button 1 is pressed


{Serial.println ("Button 1");
if (Number==0)
Number=1;
else
Number = (Number*10) + 1; //Pressed twice
}

if (key == '4') //If Button 4 is pressed


{Serial.println ("Button 4");
if (Number==0)
Number=4;
else
Number = (Number*10) + 4; //Pressed twice
}

if (key == '7') //If Button 7 is pressed


{Serial.println ("Button 7");
if (Number==0)
Number=7;
else
Number = (Number*10) + 7; //Pressed twice
}

if (key == '0')
{Serial.println ("Button 0"); //Button 0 is Pressed
if (Number==0)
Number=0;
else
Number = (Number*10) + 0; //Pressed twice
}

if (key == '2') //Button 2 is Pressed


{Serial.println ("Button 2");
if (Number==0)
Number=2;
else
Number = (Number*10) + 2; //Pressed twice
}

if (key == '5')
{Serial.println ("Button 5");
if (Number==0)
Number=5;
else
Number = (Number*10) + 5; //Pressed twice
}

if (key == '8')
{Serial.println ("Button 8");
if (Number==0)
Number=8;
else
Number = (Number*10) + 8; //Pressed twice
}

if (key == '#')
{Serial.println ("Button Equal");
Num2=Number;
result = true;
}

if (key == '3')
{Serial.println ("Button 3");
if (Number==0)
Number=3;
else
Number = (Number*10) + 3; //Pressed twice
}

if (key == '6')
{Serial.println ("Button 6");
if (Number==0)
Number=6;
else
Number = (Number*10) + 6; //Pressed twice
}

if (key == '9')
{Serial.println ("Button 9");
if (Number==0)
Number=9;
else
Number = (Number*10) + 9; //Pressed twice
}

if (key == 'A' || key == 'B' || key == 'C' || key == 'D') //Detecting Buttons on
Column 4
{
Num1 = Number;
Number =0;
if (key == 'A')
{Serial.println ("Addition"); action = '+';}
if (key == 'B')
{Serial.println ("Subtraction"); action = '-'; }
if (key == 'C')
{Serial.println ("Multiplication"); action = '*';}
if (key == 'D')
{Serial.println ("Devesion"); action = '/';}

delay(100);
}

void CalculateResult()
{
if (action=='+')
Number = Num1+Num2;

if (action=='-')
Number = Num1-Num2;
if (action=='*')
Number = Num1*Num2;

if (action=='/')
Number = Num1/Num2;
}

void DisplayResult()
{
lcd.setCursor(0, 0); // set the cursor to column 0, line 1
lcd.print(Num1); lcd.print(action); lcd.print(Num2);

if (result==true)
{lcd.print(" ="); lcd.print(Number);} //Display the result

lcd.setCursor(0, 1); // set the cursor to column 0, line 1


lcd.print(Number); //Display the result
}
12) Arduino DIY Benchtop Ph Meter

COMPONENTS AND SUPPLIES


Arduino UNO & Genuino UNO × 1

Atlas Scientific Gravity™


Analog pH Sensor
× 1

Atlas Scientific Consumer Grade


pH Probe
× 1

20x4 LCD Module


× 1

158x90x60mm enclosure
× 1

Mini breadboard
× 1

Resistor 220 ohm


× 1

Resistor 1k ohm × 1
11mm standoffs and screws
(provided with the pH sensor) × 4

Jumper wires
× 1

Acrylic sheet (plexiglass)


× 1
NECESSARY TOOLS AND MACHINES
Drill, drill bits, drywall cutter bits, files,
screwdrivers, benchtop vise, band saw, glue
gun and glue stick, soldering iron and solder,
digital caliper, ruler
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

In this project, we will be making a benchtop pH


meter using the Gravity analog pH circuit and probe
from Atlas Scientific and an Arduino Uno. Readings
will be displayed on a liquid crystal display (LCD).
Note:
- This meter was developed on a Windows computer.
It was not tested on Mac.
- The enclosure is not waterproof.
Step 1: Prepare Housing
Safety : Remember to take care when handling
tools/machinery and to wear proper safety gear such
as goggles, gloves, and respirators.
The housing used is an ABS plastic enclosure. It has
to be modified for the pH meter.
Cut opening for the LCD
a) The LCD is placed in the top portion (cover) of the
enclosure. Center a 98x40mm rectangle on the cover.
b) Put the piece in the vise and drill a 3.2mm (1/8")
pilot hole in the rectangle that was marked off.
c) Use this pilot hole as the start point for the 3.2mm
(1/8") drywall cutting bit. Since this a small job, we
will use the bit on the hand drill rather than a drywall
cutting machine. Work on the inside of the rectangle
instead of the lines as it may be a bit difficult to cut in
a straight manner with this bit on the drill.
d) Next, use a hand file to remove the excess material
and shape the rectangle to the required size.

Cut openings for BNC connector and Arduino ports


The openings for the BNC connector and Arduino
ports are on the side of the bottom portion of the
enclosure.
a) Using the dimensions provided below, mark the
center point for the circle and outlines for the two
rectangles.
b) Put the piece in the vice and cut the openings. The
circular opening is made using drill bits. The
rectangular ones are made by following a similar
process used to make the opening for the LCD.

Outfit the base plate to mount components


The base plate is used to mount the Arduino, pH
sensor and mini breadboard. 3.2mm thick acrylic sheet
is used.
a) Using a band saw, cut the acrylic sheet to
135x62.5mm.
b) Mark off the positions for the four holes as shown
below. Drill 2.38mm (3/32") diameter holes.
Countersink the holes on one side of the plate to a
depth of 3mm and diameter of 4.4mm (11/64"). This is
necessary to keep a flat under-surface when the screws
are inserted to hold the standoffs.
c) Attach the 11mm standoffs using the provided
screws. The pH sensor comes with 4 standoffs and
screws. Use two of them for the Arduino.

Step 2: Install Electronics in Housing


a) Insert the base plate into the bottom portion of the
housing. Keep in position with screws or hot glue.
b) Mount the pH sensor on the base plate. Secure to
standoffs with screws.
c) Mount the Arduino Uno onto the base plate. Secure
to standoffs with screws.

d) Add the mini breadboard onto the base plate.


e) Solder the header pins to the LCD (pins provided).
Insert LCD into the top portion of the housing and use
some hot glue to keep the screen in place.
Step 3: Wire Electronics Together

Wire the components are shown in the schematic


above.
Use the mini breadboard for the 1kΩ and 220Ω and
for distributing the Arduino's 5V and ground pins.
The two resistors are used to set the screen contrast.
Datasheets
Gravity pH sensor, pH probe
Step 4: Finalize Assembly
After the wiring has been completed:
a) Put the top and bottom portions of the housing
together using the provided screws.
b) Connect the probe to the BNC connector.
Step 5: Upload Code Onto Arduino Uno
The code for this project makes use of customized
libraries and header files. You will have to add them to
your Arduino IDE to use the code. The steps below
include the process of making this addition to the IDE.
a) Connect the Arduino to your computer and open the
IDE. The IDE can be downloaded from this LINK if
you do not have it. Go to Tools -> Board -> Select
Arduino/Genuino Uno. Go to Tools -> Port -> select
the port where the Arduino is connected to.
b) Add Liquid Crystal Display library: In the IDE go
to Sketch -> Include library -> Manage libraries. In
the search bar of the Library Manager enter
"liquidcrystal". Look for the package titled
"LiquidCrystal Built-in by Arduino, Adafruit". It may
or may not be installed. If not, select the package and
click on install.
c) Add Atlas Gravity sensor library: Download the zip
file from the following LINK. The file will be saved
as "Atlas_gravity.zip". In the IDE go to Sketch ->
Include library -> Add.ZIP Library. Locate the
"Atlas_gravity.zip" file and select to add.
d) Next, we have to add the code for the pH meter.
Copy the code from this LINK onto the IDE work
panel.
e) Compile and upload the code to the Arduino.
f) The pH readings will then be displayed on the LCD.
You can also view the readings on the serial monitor.
To open the serial monitor, go to Tools -> Serial
Monitor or press Ctrl+Shift+M on your keyboard. Set
the baud rate to 9600 and select "Carriage return".
Step 6: Calibrate pH Sensor
Note: If you plan on using an external power supply
for the Arduino, connect it to the Arduino before
doing the calibration. This will ensure that the
reference levels are appropriately set, which will aid
in the correct calibration.
This pH meter can be calibrated to one, two or three-
points calibration. Standard buffer solutions (pH 4, 7
and 10) are required
The serial monitor is used for the calibration process.
The user will be able to observe the gradual change in
readings as they come to stabilization and send the
appropriate commands.
Calibration data are stored in the EEPROM of the
Arduino.
Calibration commands
Low-point: cal, 4
Mid-point: cal, 7
High-point: cal, 10
Clear calibration: cal, clear
Steps
a) Remove the soaker bottle and rinse off the pH
probe.
b) Pour some of the pH 4 solution into a cup. Ensure
that there is enough to cover the sensing area of the
probe.
c) Place the probe in the cup and stir it around to
remove trapped air. Observe the readings on the serial
monitor. Let the probe sit in the solution until the
readings stabilize (small movement from one reading
to the next is normal)
d) After the readings stabilize, enter the command cal,
4 into the serial monitor. Calibration to pH 4 is now
complete.
Repeat steps a-d for pH7 and pH10. Remember to
rinse the probe as you proceed to different buffer
solutions.
What about temperature compensation?
The sensor used in this project has an accuracy of +/-
0.2%. The pH meter will operate within this accuracy
in the temperature range of 7 - 46°C. Outside of this
range, the meter will have to be modified for temp
compensation. Note: The pH probe can be subjected to
a range of 1 − 60 °C.

SCHEMATICS
CODE

/*
Once uploaded, open the serial monitor, set the baud rate to 9600 and
append "Carriage return"
The code allows the user to observe real time pH readings as well as
calibrate the sensor.
One, two or three-point calibration can be done.

Calibration commands:
low-point: "cal,4"
mid-point: "cal,7"
high-point: "cal,10"
clear calibration: "cal,clear"
*/

#include "ph_grav.h" //header file for Atlas Scientific


gravity pH sensor
#include "LiquidCrystal.h" //header file for liquid crystal
display (lcd)

String inputstring = ""; //a string to hold incoming data


from the PC
boolean input_string_complete = false; //a flag to indicate have we
received all the data from the PC
char inputstring_array[10]; //a char array needed for string
parsing
Gravity_pH pH = A0; //assign analog pin A0 of
Arduino to class Gravity_pH. connect output of pH sensor to pin A0
LiquidCrystal pH_lcd(2, 3, 4, 5, 6, 7); //make a variable pH_lcd
and assign arduino digital pins to lcd pins (2 -> RS, 3 -> E, 4 to 7 -> D4 to
D7)

void setup() {
Serial.begin(9600); //enable serial port
pH_lcd.begin(20, 4); //start lcd interface and define lcd
size (20 columns and 4 rows)
pH_lcd.setCursor(0,0); //place cursor on screen at
column 1, row 1
pH_lcd.print("--------------------"); //display characters
pH_lcd.setCursor(0,3); //place cursor on screen at
column 1, row 4
pH_lcd.print("--------------------"); //display characters
pH_lcd.setCursor(5, 1); //place cursor on screen at
column 6, row 2
pH_lcd.print("pH Reading"); //display "pH Reading"
if (pH.begin()) { Serial.println("Loaded EEPROM");}
Serial.println(F("Use commands \"CAL,4\", \"CAL,7\", and \"CAL,10\" to
calibrate the circuit to those respective values"));
Serial.println(F("Use command \"CAL,CLEAR\" to clear the calibration"));
}

void serialEvent() { //if the hardware serial port_0


receives a char
inputstring = Serial.readStringUntil(13); //read the string until we see
a <CR>
input_string_complete = true; //set the flag used to tell if we
have received a completed string from the PC
}

void loop() {

if (input_string_complete == true) { //check if data received


inputstring.toCharArray(inputstring_array, 30); //convert the string to a
char array
parse_cmd(inputstring_array); //send data to pars_cmd function
input_string_complete = false; //reset the flag used to tell if we
have received a completed string from the PC
inputstring = ""; //clear the string
}
Serial.println(pH.read_ph()); //output pH reading to serial
monitor
pH_lcd.setCursor(8, 2); //place cursor on screen at
column 9, row 3
pH_lcd.print(pH.read_ph()); //output pH to lcd
delay(1000);
}

void parse_cmd(char* string) { //For calling calibration


functions
strupr(string); //convert input string to uppercase

if (strcmp(string, "CAL,4") == 0) { //compare user input string


with CAL,4 and if they match, proceed
pH.cal_low(); //call function for low point calibration
Serial.println("LOW CALIBRATED");
}
else if (strcmp(string, "CAL,7") == 0) { //compare user input string
with CAL,7 and if they match, proceed
pH.cal_mid(); //call function for midpoint calibration
Serial.println("MID CALIBRATED");
}
else if (strcmp(string, "CAL,10") == 0) { //compare user input string
with CAL,10 and if they match, proceed
pH.cal_high(); //call function for highpoint calibration
Serial.println("HIGH CALIBRATED");
}
else if (strcmp(string, "CAL,CLEAR") == 0) { //compare user input
string with CAL,CLEAR and if they match, proceed
pH.cal_clear(); //call function for clearing calibration
Serial.println("CALIBRATION CLEARED");
}
}

13) Arduino Reaction Timer


COMPONENTS AND SUPPLIES
LED (generic)
× 2

SparkFun Pushbutton switch


12mm
× 2

DFRobot I2C 16x2 Arduino × 1


LCD Display Module

Slide Switch
× 1

Resistor 10k ohm


× 2

Battery Holder, 3 x AAA


× 1

Arduino Micro & Genuino


Micro
× 1
NECESSARY TOOLS AND MACHINES
Soldering iron (generic)

ABOUT THIS PROJECT

I discovered the code somewhere on the Internet and


tried it.
All my family loved the game and I decided to
assemble it in a funny case to be able to play.
The work is now finished and it is into the hands of
my kids.
It is a very basic project but in a kind of case which
hides all elements.
Here are some pictures:
This is how it looks. The BIG button is a hit button
and the small red one on top is "start"

I
was able to shrink the system and program only an
Atmega328P chip. Runs on 3 AAA.
Press Start

Round 1 of 5
Round 2 of 5

Average result calculation and showing. The "verdict"


Please do not hesitate to ask me questions if needed.
SCHEMATICS
CODE

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define btnSTART 5
#define btnHIT 7
#define ledTrigger 9
LiquidCrystal_I2C lcd(0x23,20,4);

void setup() {
lcd.init();
lcd.backlight();
pinMode(btnSTART, INPUT_PULLUP);
pinMode(btnHIT, INPUT_PULLUP);
pinMode(ledTrigger, OUTPUT);
digitalWrite(ledTrigger, LOW);
lcd.print("Salut Famille!");
delay(2000);
lcd.clear();
randomSeed(analogRead(0));
}

void loop() {
long timeReaction;
long timeTotal = 0;
lcd.print("Press START!");
while (digitalRead(btnSTART)) {}
delay(10);
while (!digitalRead(btnSTART)) {}
lcd.clear();
lcd.print("Jouez!!!");
delay(1000);
for (int i = 0; i < 5; i++) {
delay(random(500, 5000));
timeReaction = millis();
digitalWrite(ledTrigger, HIGH);
while (digitalRead(btnHIT)) {}
timeReaction = millis() - timeReaction;
timeTotal += timeReaction;
delay(10);
while (!digitalRead(btnHIT)) {}
digitalWrite(ledTrigger, LOW);
lcd.clear();
lcd.print(i + 1);
lcd.print(": ");
lcd.print(timeReaction);
delay(1000);
}
lcd.clear();
lcd.print("Moyenne = ");
lcd.print(timeTotal/5);
delay(10000);
lcd.clear();
}
14) Arduino Quizmo

COMPONENTS AND SUPPLIES


Arduino UNO & Genuino UNO
× 1

Adafruit Standard LCD - 16x2 × 1


White on Blue
Adafruit 4x3 Keypad
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

This project is related to developing a handy gadget to


help kids practice basic arithmetic operations. I
decided to make it as my kids were very lazy to look
into the books and come back very soon saying that
they have done it (specially multiplication tables).
This gadget randomly asks different questions and
evaluate kids performance.
For this you need a 4x3 keypad to interact with the
gadget and an LCD to show you results.
Once you have setup brightness using the rehestat, you
can note down the values and replace it with fixed
resistors or keep it there if you want the user to adjust
brightness as per his/her comfort.
Power up Arduino and it will ask you what kind of
quiz you want to take. Selec appropriate option and it
will start. Once you have input your answer, you need
to press * in order to submit and let the gadeget check
your answer. In order to finish the quiz or take next
one, press # and main menu will appear again. You
can increase the difficulty level from the code by
changing the maximum range of random number
generator. This gadget currently produces random
questions by using numbers from 1 to 12.

SCHEMATICS
CODE

#include <Keypad.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

long rand1,rand2,ans,ans1,opr,score,total;
char selec,selec1;
boolean quiz=false;
String stringTwo;

const byte ROWS = 4; //four rows


const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {10, 9, 8, 7}; //connect to the
row pinouts of the keypad
byte colPins[COLS] = {6,1,0}; //connect to the
column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys),
rowPins, colPins, ROWS, COLS );

void setup(){
lcd.begin(16, 2);
mk_menu();
keypad.addEventListener(keypadEvent);
}

void loop(){
selec = keypad.getKey();
while (selec==NO_KEY){
selec = keypad.getKey();
}
lcd.print(selec);
delay(500);
if (selec!=NO_KEY){
switch(selec){
case '1':
quiz=true;
opr=1;
quiz_sum();
break;
case '2':
quiz=true;
opr=2;
quiz_subt();
break;
case '3':
quiz=true;
opr=3;
quiz_mult();
break;
}
}
}

void mk_menu(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1)+ 2)- 3)x");
lcd.setCursor(0, 1);
lcd.print("Choose: ");
}
void quiz_sum(){
lcd.clear();
lcd.setCursor(0, 0);
rand1=random(1,99);
rand2=random(1,99);
lcd.print("Find ");
lcd.print(rand1);
lcd.print("+");
lcd.print(rand2);
lcd.print("?");
ans1=rand1+rand2;
selec1 = keypad.getKey();
while (selec1==NO_KEY){
selec1 = keypad.getKey();
}
while (quiz){
while (selec1==NO_KEY){
selec1 = keypad.getKey();
}
switch(selec1){
case NO_KEY:
break;
default:
lcd.print(selec1);
stringTwo.concat(selec1);
ans=stringTwo.toInt();
//lcd.print(stringTwo);
selec1=NO_KEY;
break;
}
}
}

void quiz_subt(){
lcd.clear();
lcd.setCursor(0, 0);
rand1=random(1,99);
rand2=random(1,99);
lcd.print("Find ");
if(rand1>=rand2){
lcd.print(rand1);
lcd.print("-");
lcd.print(rand2);
ans1=rand1-rand2;
}
else if(rand1<rand2){
lcd.print(rand2);
lcd.print("-");
lcd.print(rand1);
ans1=rand2-rand1;
}
lcd.print("?");
selec1 = keypad.getKey();
while (selec1==NO_KEY){
selec1 = keypad.getKey();
}
while (quiz){
while (selec1==NO_KEY){
selec1 = keypad.getKey();
}
switch(selec1){
case NO_KEY:
break;
default:
lcd.print(selec1);
stringTwo.concat(selec1);
ans=stringTwo.toInt();
//lcd.print(stringTwo);
selec1=NO_KEY;
break;
}
}
}

void quiz_mult(){
lcd.clear();
lcd.setCursor(0, 0);
rand1=random(1,12);
rand2=random(1,12);
lcd.print("Find ");
lcd.print(rand1);
lcd.print("x");
lcd.print(rand2);
lcd.print("?");
ans1=rand1*rand2;
selec1 = keypad.getKey();
while (selec1==NO_KEY){
selec1 = keypad.getKey();
}
while (quiz){
while (selec1==NO_KEY){
selec1 = keypad.getKey();
}
switch(selec1){
case NO_KEY:
break;
default:
lcd.print(selec1);
stringTwo.concat(selec1);
ans=stringTwo.toInt();
//lcd.print(stringTwo);
selec1=NO_KEY;
break;
}
}
}

void chk_ans(){
lcd.clear();
if (ans1==ans){
lcd.clear();
lcd.print("Correct");
score=score+1;
}
else {
lcd.clear();
lcd.print("Incorrect");
}
}
void keypadEvent(KeypadEvent key){
switch (keypad.getState()){
case PRESSED:
if (key == '*') {
chk_ans();
total=total+1;
stringTwo="";
delay(400);
if(opr==1){
quiz_sum();
}
else if(opr==2){
quiz_subt();
}
else if(opr==3){
quiz_mult();
}
}
else if (key == '#') {
quiz=false;
stringTwo="";
lcd.clear();
lcd.print("Your Score: ");
lcd.print(score);
lcd.print("/");
lcd.print(total);
delay(1500);
score=0;
total=0;
mk_menu();
loop();
}
break;
}
}

15) Arduino Model Train Control


COMPONENTS AND SUPPLIES
Arduino UNO & Genuino UNO
Or any compatible (i used × 1
sainsmart mega 2560)

Arduino Motor Shield R3


× 1

LED white
× 2
Photo resistor × 2

Resistor 10k ohm


× 2

Resistor 330 ohm


× 2

ABOUT THIS PROJECT

Like many people, my wish is a nice model train,


therefore I made a nice layout plan, bought a starter set,
made a table etc. It takes a long time, of course, to build
a complicated layout and in the meantime you want to
(test)ride on the track you have so far.
You can of course do so just with your transformer, but
if you do not pay attention you drive off the track. And
model trains are fragile, a drop on the floor will do
damage. So the plan is a back and forth automation.
Something like this: Arduino-railroad.
All due respect to the maker but if you pop each time
against a fence and reverse the motor directly, it will
damage the train or the gear at some time.
I figured two gates with an LED and an LDR will sense
the train.

Gate of LED and LDR


And let the Arduino decelerate, reverse and accelerate
the train.
The train blocks the light

SCHEMATICS
CODE

/*
Train control
This code is developed to "test" drive
a model train between two gates made of a LED and LDR.

Parts required:
1 - arduino uno/mega or compatible
1 - arduino motor shield R3
2 - Led brite white (5mm)
2 - Ldr (A 9013 photo resistor 5mm)
2 - 10K resistor
2 - 220 Ohm resistor
1 - model train

Created 4 October 2016


by Kitemasters

This code is part of the public domain


*/
// --------CONSTANTS (won't change)---------------

int sens_L_Pin = A4; // the pin number for ldr L


int sens_R_Pin = A5; // the pin number for ldr R
int led_L_Pin = 4; // the pin number for the L LED
int led_R_Pin = 5; // the pin number for the R LED
int motor_Pin = 3; // the pin number for the motor speed
int brake_Pin = 9; // the pin number for the motor brake
int direction_Pin = 12; // the pin number for the motor
direction
int current_sens_Pin = A0; // the pin number for the current
sensor
int read_sens_Interval = 200; // millisecs between reading sensors
int motor_Acc_Interval = 100; // millisecs between acceleration
steps
int motor_Dec_Interval = 10; // millisecs between deceleration
steps

//------------ VARIABLES (will change)---------------------

unsigned long currentMillis = 0; // stores the value of millis() in


each iteration of loop()
unsigned long previous_sens_Millis = 0; // will store the last time
sensors are read
unsigned long previous_Acc_Millis = 0; // will store time of last
acceleration step
unsigned long previous_Dec_Millis = 0; // will store time of last
deceleration step

int sensLreading = 0; // declare variable and set value for


left sensor reading
int sensRreading = 0; // declare variable and set value for
right sensor reading
int max_Speed = 200; // declare variable and set value for
maximum Speed (0 to 255)
int Speed = 0; // declare variable and set value for
current Speed (0 to 255)
boolean direct = HIGH; // declare variable and set value for
direction to HIGH (HIGH = left)

#define STATE_START 1 // declare value 0 to be


STATE_START
#define STATE_RUN 2 // declare value 1 to be
STATE_RUN
#define STATE_DECELERATE 3 // declare value 2 to be
STATE_DECELERATE
#define STATE_TURN 4 // declare value 3 to be
STATE_TURN
#define STATE_ACCELERATE 5 // declare value 4 to be
STATE_ACCELERATE
int state = STATE_START; // declare variable "state" and set
value to STATE_START

//========================================

void setup() {

Serial.begin(9600);

pinMode(led_L_Pin, OUTPUT); // set led_L_Pin as output


pinMode(led_R_Pin, OUTPUT); // set led_R_Pin as output
pinMode(motor_Pin, OUTPUT); // set motor_Pin as output
pinMode(brake_Pin, OUTPUT); // set brake_Pin as output
pinMode(direction_Pin, OUTPUT); // set direction_Pin as output
pinMode(sens_L_Pin, INPUT); // set sens_L_Pin as input
pinMode(sens_R_Pin, INPUT); // set sens_R_Pin as input
pinMode(current_sens_Pin, INPUT); // set current_sens_Pin as
input

}
//========================================

void loop() {

currentMillis = millis(); // store the latest value of millis()


read_sens(); // read the sensors

switch (state) // state switch


{
case STATE_START:
Start();
break;

case STATE_ACCELERATE:
Accelerate();
break;

case STATE_DECELERATE:
Decelerate();
break;

case STATE_TURN:
Turn();
break;

case STATE_RUN:
break;
}
}
//========================================

void read_sens() {

if (currentMillis - previous_sens_Millis >= read_sens_Interval) { // time is


up, so read sensors
previous_sens_Millis = currentMillis; // because shooter
and Koepel told me so.// save the time we last read sensors
sensLreading = analogRead(sens_L_Pin); // read left ldr
(high value means the light is off or blockt)
sensRreading = analogRead(sens_R_Pin); // read right ldr
(high value means the light is off or blockt)

if (sensLreading > 200 && direct == HIGH) { // if conditions


are throu, the train reached left gate***
digitalWrite(led_L_Pin, LOW); // turn left LED off
digitalWrite(led_R_Pin, HIGH); // turn right LED on
state = STATE_DECELERATE; // set state to
"decelerate"
previous_Dec_Millis = currentMillis; // set
previous_Dec_Millis to current time
}

if (sensRreading > 200 && direct == LOW) { // if conditions


are throu, the train reached right gate***
digitalWrite(led_R_Pin, LOW); // turn right LED off
digitalWrite(led_L_Pin, HIGH); // turn left LED on
state = STATE_DECELERATE; // set state to
"decelerate"
previous_Dec_Millis = currentMillis; // set
previous_Dec_Millis to current time
}
}
}
//========================================

void Start() {

digitalWrite(led_L_Pin, HIGH); // turn left led on


digitalWrite(brake_Pin, LOW); // Disengage the
Brake
digitalWrite(direction_Pin, direct); // Establishes
direction of the train
state = STATE_ACCELERATE; // set state to
"accelerate"
previous_Acc_Millis = currentMillis; // set
previous_Acc_Millis to current time
}
//========================================

void Accelerate() {

if (currentMillis - previous_Acc_Millis >= motor_Acc_Interval) { //


check interval time
previous_Acc_Millis = currentMillis; // because shooter
and Koepel told me so.//last time of acceleration step
Speed = Speed + 1; // add 1 to speed
analogWrite(motor_Pin, Speed); // send Speed to
motor_Pin
if (Speed == max_Speed) { // if speed reach max
speed
state = STATE_RUN; // set state to "run"
}
}
}
//========================================

void Decelerate() {
if (currentMillis - previous_Dec_Millis >= motor_Dec_Interval) { //
check interval time
previous_Dec_Millis = currentMillis; // because shooter
and Koepel told me so.//last time of acceleration step
Speed = Speed - 1; // subtract 1 of speed
analogWrite(motor_Pin, Speed); // send Speed to
motor_Pin
if (Speed == 0) { // if speed reach 0
state = STATE_TURN; // set state to "turn"
}
}
}
//========================================

void Turn() {

if (direct == HIGH) { // flip direction


direct = LOW;
digitalWrite(direction_Pin, direct); // establishes right
direction of train
}
else {
direct = HIGH;
digitalWrite(direction_Pin, direct); // establishes left
direction of train
}
state = STATE_ACCELERATE; // set state to
"accelerate"
previous_Acc_Millis = currentMillis; // set
previous_Acc_Millis to current time
}
//========================================END
16) Arduino LED Rotation Display
COMPONENTS AND SUPPLIES
Arduino UNO & Genuino UNO
Or any compatible (i used × 1
sainsmart mega 2560)
ABOUT THIS PROJECT

For the development of this project it is necessary:


* 1 x 12V DC Motor
* 10 x RGB LEDs or LED diode
* Arduino board
* configuration
* 9V battery
* Photo diode
Let's begin:
photo diode refistruje when it crossed over the LEDs and
thus knows that he visited one round.

On the motor shaft you find the card that is attached


Arduino control unit "MEGA 2650".
On the Arduino Mega little need to connect shield with
RGB LEDs.

Shield with RGB LEDs containing 10 LEDs which is


connected to a GND pins are distributed across the board
to the contacts that go to pins 24 to 52 in the Arduino
Mega
Coupled looks like
SCHEMATICS
CODE

Arduino code Led diode

/*Arduino team politehnika


Led display vazdušni
*/
int StartPin=A0;
int t=1700;
void setup(){
pinMode(2,OUTPUT); pinMode(3,OUTPUT);
pinMode(4,OUTPUT); pinMode(5,OUTPUT);
pinMode(6,OUTPUT); pinMode(11,OUTPUT);
pinMode(8,OUTPUT); pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
}
void loop(){
int val=analogRead(StartPin);
while(val < 200){
O();
A();
C();

val=analogRead(StartPin);
}
}
void A(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,0,0,0,0,0,0,0);
signal(1,0,1,1,1,1,1,1,1);
signal(0,1,1,1,0,1,1,1,1);
signal(0,1,1,1,0,1,1,1,1);
signal(1,0,1,1,0,1,1,1,1);
signal(1,1,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void B(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,0,0,0,1);
signal(0,0,0,0,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void C(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(1,0,0,0,0,0,0,0,1);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void D(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,0,0,0,0,0,1,1);
signal(1,0,1,1,1,1,1,0,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void E(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void Fa(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(0,1,1,0,1,1,1,1,1);
signal(0,1,1,0,1,1,1,1,1);
signal(0,1,1,0,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void G(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,0,1,1,1);
signal(1,0,1,1,1,0,0,0,1);
signal(0,1,1,1,1,0,1,1,0);
signal(0,1,1,1,1,0,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(1,0,0,0,0,0,0,0,1);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void H(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,0,0,1,1,1,1);
signal(1,1,1,0,0,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void I(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void J(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,0,0,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void K(){//LOW=1 HIGH=0
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,1,1,1,0,0,0);
signal(1,1,1,0,1,0,1,1,1);
signal(1,1,1,1,0,1,1,1,1);
signal(1,1,1,1,0,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void L(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void M(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(1,0,0,0,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void N(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,1,0,1,1);
signal(1,1,1,1,1,0,1,1,1);
signal(1,1,1,1,0,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void O(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void P(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,1,1,1,1);
signal(0,1,1,1,1,0,1,1,1);
signal(0,1,1,1,1,0,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void R(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,0,0,0,0,1,1,0,1);
signal(0,1,1,1,1,0,0,1,1);
signal(0,1,1,1,1,0,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void S(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void T(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,1);
signal(0,0,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void U(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,0,0,1,1);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,0,1);
signal(1,0,0,0,0,0,0,1,1);
signal(1,1,1,1,1,1,1,1,1);
delay(t);
}
void V(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,1,1,1,1,1);
signal(1,1,1,1,1,0,1,1,1);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,0,1,1,1);
signal(0,0,0,0,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
}
void Z(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,0,1);
signal(0,0,1,1,1,1,1,0,1);
signal(0,1,0,1,1,1,1,0,1);
signal(0,1,1,0,1,1,1,0,1);
signal(0,1,1,1,0,1,1,0,1);
signal(0,1,1,1,1,0,0,0,1);
signal(1,1,1,1,1,1,1,1,1);
}

void signal(int a,int b,int c,int d,int e,int f,int p,int k,int n){
/*Napomena 1=LOW 0=HIGH*/
if(a==1)digitalWrite(2,LOW);
else digitalWrite(2,HIGH);
if(b==1)digitalWrite(3,LOW);
else digitalWrite(3,HIGH);
if(c==1)digitalWrite(4,LOW);
else digitalWrite(4,HIGH);
if(d==1)digitalWrite(5,LOW);
else digitalWrite(5,HIGH);
if(e==1)digitalWrite(6,LOW);
else digitalWrite(6,HIGH);
if(f==1)digitalWrite(11,LOW);
else digitalWrite(11,HIGH);
if(p==1)digitalWrite(8,LOW);
else digitalWrite(8,HIGH);
if(k==1)digitalWrite(9,LOW);
else digitalWrite(9,HIGH);
if(n==1)digitalWrite(10,LOW);
else digitalWrite(10,HIGH);
delay(t);
}

Arduino code RGB led

/*Arduino team politehnika


Led display vazdušni
*/
int StartPin=A0;
int t=2000;
void setup(){
//Red pins leds dioda
pinMode(28,OUTPUT); pinMode(45,OUTPUT);
pinMode(33,OUTPUT); pinMode(46,OUTPUT);
pinMode(34,OUTPUT); pinMode(51,OUTPUT);
pinMode(39,OUTPUT); pinMode(52,OUTPUT);
pinMode(40,OUTPUT);
//Green pins leds dioda
pinMode(29,OUTPUT); pinMode(42,OUTPUT);
pinMode(30,OUTPUT); pinMode(47,OUTPUT);
pinMode(35,OUTPUT); pinMode(48,OUTPUT);
pinMode(36,OUTPUT); pinMode(53,OUTPUT);
pinMode(41,OUTPUT);
//Blue pins leds dioda
pinMode(26,OUTPUT); pinMode(43,OUTPUT);
pinMode(31,OUTPUT); pinMode(44,OUTPUT);
pinMode(32,OUTPUT); pinMode(49,OUTPUT);
pinMode(37,OUTPUT); pinMode(50,OUTPUT);
pinMode(38,OUTPUT);
}
void loop(){
int val=analogRead(StartPin);
while(val < 200){
O();
AAA();
CC();

val=analogRead(StartPin);
}
}
void A(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,0,0,0,0,0,0,0);
signal(1,0,1,1,1,1,1,1,1);
signal(0,1,1,1,0,1,1,1,1);
signal(0,1,1,1,0,1,1,1,1);
signal(1,0,1,1,0,1,1,1,1);
signal(1,1,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void B(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,0,0,0,1);
signal(0,0,0,0,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void C(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(1,0,0,0,0,0,0,0,1);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void D(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,0,0,0,0,0,1,1);
signal(1,0,1,1,1,1,1,0,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void E(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,1,1,1,0,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void Fa(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(0,1,1,0,1,1,1,1,1);
signal(0,1,1,0,1,1,1,1,1);
signal(0,1,1,0,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void G(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,0,1,1,1);
signal(1,0,1,1,1,0,0,0,1);
signal(0,1,1,1,1,0,1,1,0);
signal(0,1,1,1,1,0,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(1,0,0,0,0,0,0,0,1);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void H(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,0,0,1,1,1,1);
signal(1,1,1,0,0,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void I(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void J(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,0,0,1);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void K(){//LOW=1 HIGH=0
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,1,1,1,0,0,0);
signal(1,1,1,0,1,0,1,1,1);
signal(1,1,1,1,0,1,1,1,1);
signal(1,1,1,1,0,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void L(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void M(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(1,0,0,0,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void N(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,1,0,1,1);
signal(1,1,1,1,1,0,1,1,1);
signal(1,1,1,1,0,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void O(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,1,1,1,1,1,1,1,0);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void P(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,1,1,1,1);
signal(0,1,1,1,1,0,1,1,1);
signal(0,1,1,1,1,0,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void R(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,0,0,0,0,1,1,0,1);
signal(0,1,1,1,1,0,0,1,1);
signal(0,1,1,1,1,0,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void S(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void T(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,1,1);
signal(0,0,0,0,0,0,0,0,0);
signal(0,1,1,1,1,1,1,1,1);
signal(0,0,1,1,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void U(){
signal(1,1,1,1,1,1,1,1,1);
signal(1,0,0,0,0,0,0,1,1);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,0,1);
signal(1,0,0,0,0,0,0,1,1);
signal(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void V(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,0,0,0,1,1,1,1,1);
signal(1,1,1,1,1,0,1,1,1);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,1,1,1,0);
signal(1,1,1,1,1,1,1,0,1);
signal(1,1,1,1,1,0,1,1,1);
signal(0,0,0,0,1,1,1,1,1);
signal(1,1,1,1,1,1,1,1,1);
}
void Z(){
signal(1,1,1,1,1,1,1,1,1);
signal(0,1,1,1,1,1,1,0,1);
signal(0,0,1,1,1,1,1,0,1);
signal(0,1,0,1,1,1,1,0,1);
signal(0,1,1,0,1,1,1,0,1);
signal(0,1,1,1,0,1,1,0,1);
signal(0,1,1,1,1,0,0,0,1);
signal(1,1,1,1,1,1,1,1,1);
}
void AA(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,0,0,0,0,0,0,0);
signal1(1,0,1,1,1,1,1,1,1);
signal1(0,1,1,1,0,1,1,1,1);
signal1(0,1,1,1,0,1,1,1,1);
signal1(1,0,1,1,0,1,1,1,1);
signal1(1,1,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void BB(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,0,0,0,1);
signal1(0,0,0,0,0,1,1,1,0);
signal1(0,1,1,1,0,1,1,1,0);
signal1(0,1,1,1,0,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void CC(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(1,0,0,0,0,0,0,0,1);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void DD(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,0,0,0,0,0,1,1);
signal1(1,0,1,1,1,1,1,0,1);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void EE(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,0,1,1,1,0);
signal1(0,1,1,1,0,1,1,1,0);
signal1(0,1,1,1,0,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void FF(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,1);
signal1(0,1,1,0,1,1,1,1,1);
signal1(0,1,1,0,1,1,1,1,1);
signal1(0,1,1,0,1,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void GG(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,0,1,1,1);
signal1(1,0,1,1,1,0,0,0,1);
signal1(0,1,1,1,1,0,1,1,0);
signal1(0,1,1,1,1,0,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(1,0,0,0,0,0,0,0,1);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void HH(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,0,0,1,1,1,1);
signal1(1,1,1,0,0,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void II(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void JJ(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,0,0,1);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void KK(){//LOW=1 HIGH=0
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,0,0,1,1,1,0,0,0);
signal1(1,1,1,0,1,0,1,1,1);
signal1(1,1,1,1,0,1,1,1,1);
signal1(1,1,1,1,0,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void LL(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void MM(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,0,0,0,0,0,0,0,0);
signal1(0,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,1);
signal1(1,0,0,0,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,1);
signal1(1,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void NN(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,0,1);
signal1(1,1,1,1,1,1,0,1,1);
signal1(1,1,1,1,1,0,1,1,1);
signal1(1,1,1,1,0,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void OO(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,1,1,1,1,1,1,1,0);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void PP(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,0,0,0,0,1,1,1,1);
signal1(0,1,1,1,1,0,1,1,1);
signal1(0,1,1,1,1,0,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void RR(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,0,0,0,0,1,1,0,1);
signal1(0,1,1,1,1,0,0,1,1);
signal1(0,1,1,1,1,0,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
/*void SS(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}*/
void TT(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,0,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,1,1);
signal1(0,0,0,0,0,0,0,0,0);
signal1(0,1,1,1,1,1,1,1,1);
signal1(0,0,1,1,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void UU(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(1,0,0,0,0,0,0,1,1);
signal1(1,1,1,1,1,1,1,0,1);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,0,1);
signal1(1,0,0,0,0,0,0,1,1);
signal1(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void VV(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,0,0,0,1,1,1,1,1);
signal1(1,1,1,1,1,0,1,1,1);
signal1(1,1,1,1,1,1,1,0,1);
signal1(1,1,1,1,1,1,1,1,0);
signal1(1,1,1,1,1,1,1,0,1);
signal1(1,1,1,1,1,0,1,1,1);
signal1(0,0,0,0,1,1,1,1,1);
signal1(1,1,1,1,1,1,1,1,1);
}
void ZZ(){
signal1(1,1,1,1,1,1,1,1,1);
signal1(0,1,1,1,1,1,1,0,1);
signal1(0,0,1,1,1,1,1,0,1);
signal1(0,1,0,1,1,1,1,0,1);
signal1(0,1,1,0,1,1,1,0,1);
signal1(0,1,1,1,0,1,1,0,1);
signal1(0,1,1,1,1,0,0,0,1);
signal1(1,1,1,1,1,1,1,1,1);
}

void AAA(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,0,0,0,0,0,0,0);
signal2(1,0,1,1,1,1,1,1,1);
signal2(0,1,1,1,0,1,1,1,1);
signal2(0,1,1,1,0,1,1,1,1);
signal2(1,0,1,1,0,1,1,1,1);
signal2(1,1,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void BBB(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,0,0,0,1);
signal2(0,0,0,0,0,1,1,1,0);
signal2(0,1,1,1,0,1,1,1,0);
signal2(0,1,1,1,0,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void CCC(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(1,0,0,0,0,0,0,0,1);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void DDD(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,0,0,0,0,0,1,1);
signal2(1,0,1,1,1,1,1,0,1);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void EEE(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,0,1,1,1,0);
signal2(0,1,1,1,0,1,1,1,0);
signal2(0,1,1,1,0,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void FFF(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,1);
signal2(0,1,1,0,1,1,1,1,1);
signal2(0,1,1,0,1,1,1,1,1);
signal2(0,1,1,0,1,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void GGG(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,0,1,1,1);
signal2(1,0,1,1,1,0,0,0,1);
signal2(0,1,1,1,1,0,1,1,0);
signal2(0,1,1,1,1,0,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(1,0,0,0,0,0,0,0,1);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void HHH(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,0,0,1,1,1,1);
signal2(1,1,1,0,0,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void III(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void JJJ(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,0,0,1);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void KKK(){//LOW=1 HIGH=0
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,0,0,1,1,1,0,0,0);
signal2(1,1,1,0,1,0,1,1,1);
signal2(1,1,1,1,0,1,1,1,1);
signal2(1,1,1,1,0,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void LLL(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void MMM(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,0,0,0,0,0,0,0,0);
signal2(0,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,1);
signal2(1,0,0,0,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,1);
signal2(1,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void NNN(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,0,1);
signal2(1,1,1,1,1,1,0,1,1);
signal2(1,1,1,1,1,0,1,1,1);
signal2(1,1,1,1,0,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void OOO(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,1,1,1,1,1,1,1,0);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void PPP(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,0,0,0,0,1,1,1,1);
signal2(0,1,1,1,1,0,1,1,1);
signal2(0,1,1,1,1,0,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void RRR(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,0,0,0,0,1,1,0,1);
signal2(0,1,1,1,1,0,0,1,1);
signal2(0,1,1,1,1,0,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void SSS(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void TTT(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,0,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,1,1);
signal2(0,0,0,0,0,0,0,0,0);
signal2(0,1,1,1,1,1,1,1,1);
signal2(0,0,1,1,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void UUU(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(1,0,0,0,0,0,0,1,1);
signal2(1,1,1,1,1,1,1,0,1);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,0,1);
signal2(1,0,0,0,0,0,0,1,1);
signal2(1,1,1,1,1,1,1,1,1);
delayMicroseconds(t);
}
void VVV(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,0,0,0,1,1,1,1,1);
signal2(1,1,1,1,1,0,1,1,1);
signal2(1,1,1,1,1,1,1,0,1);
signal2(1,1,1,1,1,1,1,1,0);
signal2(1,1,1,1,1,1,1,0,1);
signal2(1,1,1,1,1,0,1,1,1);
signal2(0,0,0,0,1,1,1,1,1);
signal2(1,1,1,1,1,1,1,1,1);
}
void ZZZ(){
signal2(1,1,1,1,1,1,1,1,1);
signal2(0,1,1,1,1,1,1,0,1);
signal2(0,0,1,1,1,1,1,0,1);
signal2(0,1,0,1,1,1,1,0,1);
signal2(0,1,1,0,1,1,1,0,1);
signal2(0,1,1,1,0,1,1,0,1);
signal2(0,1,1,1,1,0,0,0,1);
signal2(1,1,1,1,1,1,1,1,1);
}

void signal(int a,int b,int c,int d,int e,int f,int p,int k,int n){
/*Napomena 1=LOW 0=HIGH*/
if(a==1)digitalWrite(52,LOW);
else digitalWrite(52,HIGH);
if(b==1)digitalWrite(51,LOW);
else digitalWrite(51,HIGH);
if(c==1)digitalWrite(46,LOW);
else digitalWrite(46,HIGH);
if(d==1)digitalWrite(45,LOW);
else digitalWrite(45,HIGH);
if(e==1)digitalWrite(40,LOW);
else digitalWrite(40,HIGH);
if(f==1)digitalWrite(39,LOW);
else digitalWrite(39,HIGH);
if(p==1)digitalWrite(34,LOW);
else digitalWrite(34,HIGH);
if(k==1)digitalWrite(33,LOW);
else digitalWrite(33,HIGH);
if(n==1)digitalWrite(28,LOW);
else digitalWrite(28,HIGH);
delayMicroseconds(t);
}

void signal1(int a,int b,int c,int d,int e,int f,int p,int k,int n){
/*Napomena 1=LOW 0=HIGH*/
if(a==1)digitalWrite(53,LOW);
else digitalWrite(53,HIGH);
if(b==1)digitalWrite(48,LOW);
else digitalWrite(48,HIGH);
if(c==1)digitalWrite(47,LOW);
else digitalWrite(47,HIGH);
if(d==1)digitalWrite(42,LOW);
else digitalWrite(42,HIGH);
if(e==1)digitalWrite(41,LOW);
else digitalWrite(41,HIGH);
if(f==1)digitalWrite(36,LOW);
else digitalWrite(36,HIGH);
if(p==1)digitalWrite(35,LOW);
else digitalWrite(35,HIGH);
if(k==1)digitalWrite(30,LOW);
else digitalWrite(30,HIGH);
if(n==1)digitalWrite(29,LOW);
else digitalWrite(29,HIGH);
delayMicroseconds(t);
}

void signal2(int a,int b,int c,int d,int e,int f,int p,int k,int n){
/*Napomena 1=LOW 0=HIGH*/
if(a==1)digitalWrite(50,LOW);
else digitalWrite(50,HIGH);
if(b==1)digitalWrite(49,LOW);
else digitalWrite(49,HIGH);
if(c==1)digitalWrite(44,LOW);
else digitalWrite(44,HIGH);
if(d==1)digitalWrite(43,LOW);
else digitalWrite(43,HIGH);
if(e==1)digitalWrite(38,LOW);
else digitalWrite(38,HIGH);
if(f==1)digitalWrite(37,LOW);
else digitalWrite(37,HIGH);
if(p==1)digitalWrite(32,LOW);
else digitalWrite(32,HIGH);
if(k==1)digitalWrite(31,LOW);
else digitalWrite(31,HIGH);
if(n==1)digitalWrite(26,LOW);
else digitalWrite(26,HIGH);
delayMicroseconds(t);
}
17) Arduino Fast IR Game with Any Remote Control
COMPONENTS AND SUPPLIES
Arduino Nano R3
It also worked with an UNO × 1

Adafruit Standard LCD - 16x2


White on Blue
× 1
with I2C connection

IR receiver (generic) × 1
Jumper wires (generic)
× 11

Any Remote Control


× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

I didn't use the IR receiver until this project, so I decided


to make the control via remote control. It was also
important for me to make the program learn which keys
you want to use. So you don not have to figure out what
kind of value you need for all the keys you use and put it
in the code. You just teach the game once you started it
which key ist up, down, left and so on. Well, you have to
do this every time you reset the board...
You can see a level 3 gameplay. An 'arrow down' coming
from the left. Push the key for 'arrow down'
Everytime you hit a wrong key, the symbol went to the
other side of the screen or you hit the key while the
symbol is behind a fence the score gets less. Otherwise
the score goes up.

Left corner shows level, right corner shows Score. Score


less then 0 means 'Game Over'
SCHEMATICS

I did not find an LCD with I2C board (LCD 1602 +


I2C HD44780 Modul). So I just made a shematic. My
IR Diode (VS1838B LIRC) is connected like in this
sheme, but make shure you make the right
connection!! (Data: orange, GND: black, VCC: red).
You can use an Arduino Nano or Uno.
CODE
#include <IRremote.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
char up = 3;
char down = 1;
char ok = 2;

// Define 3 characters for the LCD Display


byte up1[8] = {
B00100,
B01110,
B10101,
B00100,
B00100,
B00100,
B00100,
B00100
};

byte down1[8] = {
B00100,
B00100,
B00100,
B00100,
B00100,
B10101,
B01110,
B00100
};

byte ok1[8] = {
B01110,
B01010,
B01110,
B10000,
B10100,
B11000,
B10100,
B10010
};

int RECV_PIN = 11; // IR Sensor on Pin 11


char* howtoplay[23] = {
"> FAST IR GAME <",
" Press key ",
"You have to", // if you don't want this howToPlay you can delete from
here ...
"press the key,",
"that you see on",
"the screen, when",
"it is beetween",
"the fences (#).",
"It ist getting",
"faster and there",
"will be symbols",
"that you do not",
"have to hit!",
"Try to get to",
"Level 10 and win",
"the game. Before",
"you start, you",
"have to define",
"the keys on your",
"remote control",
"to play the game", // ... until here. Leave the last lines for propper work!
" Have fun !!",
""
};

String keyNames[] = {"up", "down", "right", "left", "ok", "+", "-", "#",
"*"};
String keySymb[] = {"", "", "", "", "", "", "", "", ""};
long keys[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int keycount = 7;

int lev;
int xpos = 1;
int xadd = 1;
int xleft;
int xright;
int xstart = 0;
int xend = 15;

int actSym = 0;
int score; // All together score
int scorePerLev; // Symbols in actual level
int scoreNextLev = 50; // Symbols until next level

int gameState = -1;

bool pressed = false;

IRrecv irrecv(RECV_PIN);
decode_results results;

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16
chars and 2 line display

void setup()
{
Serial.begin(9600);
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.createChar(up, up1);
lcd.createChar(down, down1);
lcd.createChar(ok, ok1);
keySymb[0] = "\3";
keySymb[1] = "\1";
keySymb[2] = "\176";
keySymb[3] = "\177";
keySymb[4] = "\2";
keySymb[5] = "+";
keySymb[6] = "-";
keySymb[7] = "#";
keySymb[8] = "*";

irrecv.enableIRIn(); // Start the receiver


info(); //howtoplay show once at the start, can be removed when you know
how to play
randomSeed(analogRead(1));
}

void loop()
{

// define keys only once


// gameState= -1
// ################################
if (gameState == -1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Define Keys to");
lcd.setCursor(0, 1);
lcd.print("play the game...");
delay(3000);
pressed = false;
for (int i = 0; i < keycount; i++) { // 0 und 5
pressed = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Key for:");
lcd.print(keyNames[i]);
while (pressed != true) {
if (irrecv.decode(&results)) {
keys[i] = results.value;
lcd.setCursor(0, 1);
lcd.print(" ok!");
Serial.println(keys[i]);
delay(500);
irrecv.resume(); // Receive the next value
pressed = true;
}
}
pressed = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Repaet key!");
lcd.print(keyNames[i]);
irrecv.resume();
while (pressed != true) {
if (irrecv.decode(&results)) {
if (keys[i] == results.value) {
lcd.setCursor(0, 1);
lcd.print("is the same!");
delay(500);
pressed = true;
} else {
lcd.setCursor(0, 1);
lcd.print("wrong!");
delay(500);
lcd.setCursor(0, 1);
lcd.print(" ");
}
irrecv.resume();
}
}
}
gameState = 0; // ok to select level
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Keys done!");
delay(2000);
}

// Select Level
// gameState=0
//###########################
if (gameState == 0) {
lev = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Select Level+ok");
lcd.setCursor(0, 1);
lcd.print("Level: ");
lcd.print(lev);
irrecv.resume();
pressed = false;
Serial.println("Level");
Serial.println(pressed);
while (pressed != true) {
if (irrecv.decode(&results)) {
Serial.println(results.value);
if (results.value == keys[0]) lev++;
if (results.value == keys[1]) lev--;
if (results.value == keys[4]) pressed = true;
if (lev < 1) lev = 1;
if (lev > 10) lev = 10;
lcd.setCursor(7, 1);
lcd.print(lev);
lcd.print(" ");
irrecv.resume();
}
delay(250);
}
lcd.setCursor(0, 0);
lcd.print("Ok! Play in ");
delay(2000);
lcd.clear();
gameState = 1; // Main gameplay
score = 0;
scorePerLev = 0;
keycount = 7;
xleft = 4;
xright = 11;
drawField("");
irrecv.resume();
Serial.println("Level Set");
}

// Main Game
// gameState=1
//###############################
if (gameState == 1) {
xpos = 0;
xadd = 1;
int k = 0;
bool rightkey = false;
pressed = false;
actSym = floor(random(0, keycount));
while (pressed != true) {
Serial.println(xpos);
if (irrecv.decode(&results)) {
for (int i = 0; i < keycount; i++) {
if (results.value == keys[i]) {
rightkey = true;
k = i;
}
}
if (rightkey == true) {
scorePerLev++;
if (xpos <= xleft || xpos >= xright) {
score = score - (4 + lev);
// negativ sound
}
if (actSym == k) {
lcd.setCursor(xpos, 1);
lcd.print(" ");
score++;
drawField("");
changeDirection();
} else {
score = score - (2 + lev);
drawField(" :( ");
// negativ sound
}
actSym = floor(random(0, keycount));
rightkey = false;
}
delay(10);
irrecv.resume();
if (scorePerLev == scoreNextLev) {
scorePerLev = 0;
lev++;
drawField("");
if (lev < 11) {
lcd.setCursor(0, 1);
lcd.print("Next level!");
waitForOK();
// Check for score and display message here later
lcd.setCursor(0, 1);
lcd.print(" ");
} else {
gameState = 5;
pressed = true;
}
}
}
lcd.setCursor(xpos, 1);
lcd.print(" ");
xpos = xpos + xadd;
if (xpos == xend + 1 || xpos == xstart - 1) {
if (actSym < 7) {
score = score - (2 * (lev + 5));
drawField(" :( ");
} else {
drawField("");
}
changeDirection();
actSym = floor(random(0, keycount));
// negativ sound
}
lcd.setCursor(xpos, 1);
lcd.print(keySymb[actSym]);
delay(200 - (lev * 10));
if (score < 0) {
gameState = 9;
pressed = true;
}
} // Main Game loop End

}
// Win
// ##################
if (gameState == 5) {
// positiv sound
lcd.setCursor(0, 1);
lcd.print("You win the Game");
lcd.setCursor(0, 0);
lcd.print("Bravo! ");
waitForOK();
gameState = 0;
}

// Game Over
// ##################
if (gameState == 9) {
// negativ sound
for (int i = 0; i < 5; i++) {
lcd.setCursor(0, 1);
lcd.print(" ");
delay(200);
lcd.setCursor(0, 1);
lcd.print(" Game over! ");
delay(300);
}
waitForOK();
gameState = 0;
}

void info () {
int i = 0;
while (howtoplay[i] != "") {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(howtoplay[i]);
lcd.setCursor(0, 1);
lcd.print(howtoplay[i + 1]);
delay(300);
waitForKey();
i++;
}
irrecv.resume();
}

void drawField(String empty) {


Serial.println("drawField");
int SCur;
if (empty == "") empty = " ";
lcd.setCursor(0, 0);
lcd.print("################");
if (lev > 3) {
xleft = floor(random(4, 7));
xright = xleft + 7;
if (lev > 6) xright = xleft + 6;
if (lev > 9) xright = xleft + 5;
}
if (lev > 4) keycount = 8;
if (lev > 6) keycount = 9;
lcd.setCursor(xleft + 1, 0);
lcd.print(empty.substring(0, xright - xleft - 1));
lcd.setCursor(0, 0);
lcd.print("L");
lcd.print(lev);
if (score < 1000) SCur = 13;
if (score < 100) SCur = 14;
if (score < 10) SCur = 15;
if (score < 0) SCur = 14;
lcd.setCursor(SCur, 0);
lcd.print(score);
}

void changeDirection() {
xpos = xstart;
xadd = 1;
if (lev > 3) {
int dir = floor(random(0, 2));
if (dir == 1) {
xpos = xend;
xadd = -1;
}
}
}

void waitForKey () {
bool press = false;
irrecv.resume();
while (press == false) {
if (irrecv.decode(&results)) {
if (results.value != 0) press = true;
irrecv.resume();
delay(200);
}
}
}

void waitForOK() {
delay(1000);
bool press = false;
irrecv.resume();
while (press == false) {
if (irrecv.decode(&results)) {
if (results.value == keys[4]) press = true;
irrecv.resume();
delay(200);
}
}
}
18) Arduino DIY PH Dosing Pump
COMPONENTS AND SUPPLIES

Arduino UNO & Genuino UNO


× 1

pH UP/pH DOWN Solution


× 1

Resistor 4.75k ohm × 2


5 pin header
× 2

Atlas Scientific Peristaltic Pump


Kit
× 2

Atlas Scientific pH Sensor Kit


× 1

Breadboard (generic)
× 1

Male/Male Jumper Wires


× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

We will be making a pH dosing system. It has the


capability of maintaining the sample within a defined
pH range, in this case, 8-8.5. If the readings go out of
range, small amounts of either pH UP or pH
DOWN solution is automatically added to the sample
until the readings return within the limits. The pH
level will be monitored by the EZO pH sensor while
the UP/DOWN solutions will be dispensed
using peristaltic pumps. Operation is via I2C protocol
and readings are displayed on the Arduino serial
monitor
Step 1: Pre-assembly Requirements
a) Calibrate pH sensor and pumps.
b) Set the pH sensor and pumps protocol to I2C and
each device needs a unique I2C address. In accordance
with the sample code for this project, the following
addresses are used: pH sensor address is 99, pump for
pH UP solution is 103 and pump for pH DOWN
solution is 104. For information on how to change
between modes and set addresses, refer to this LINK.
The calibration and the switch to I2C MUST be done
before implementing the sensors into this project.
Step 2: Assemble Hardware

Connect the hardware as shown in the schematic.


The peristaltic pump has two power lines. The line
that goes to the Arduino's 5V pin is for the circuitry
attached to the pump while the external 12V supply is
for the pump itself. The five pin headers are used to
mount the data cables of the pumps to the breadboard
after which jumper wires make the appropriate
connections to the Arduino.
The two 4.7kΩ resistors serve as pull up resistors for
the SDA (Serial Data) and SCL (Serial Clock) lines.
Step 3: Load Program onto Arduino
The code for this project makes use of a customized
library and header file for the EZO circuits in I2C
mode. You will have to add them to your Arduino IDE
in order to use the code. The steps below include the
process of making this addition to the IDE.
a) Download Ezo_I2c_lib, a zip folder from GitHub
onto your computer.
b) On your computer, open the Arduino IDE (You can
download the IDE from HERE if you do not have it).
c) In the IDE, go to Sketch -> Include Library ->
Add.ZIP Library -> Select the Ezo_I2c_lib folder you
just downloaded. The appropriate files are now
included.
d) Copy the code from pH_dosing_pump onto your
Arduino work panel. You can also access this code
from the Ezo_I2c_lib folder downloaded above.
e) Compile and upload the pH_dosing_pump code to
your Arduino UNO.
f) Readings are displayed on the serial monitor. To
open the serial monitor, go to Tools -> Serial
Monitor or press Ctrl+Shift+M on your keyboard. Set
the baud rate to 9600 and select "Carriage return". The
pH readings should display and the pumps will be
triggered accordingly to dispense pH UP and pH
DOWN solution. Remember this sample code takes
into consideration the pH between 8-8.5, so the pumps
will only turn on when out of this range.

SCHEMATICS
CODE

/*

It was tested on an Arduino UNO.


Real time pH monitoring is done using the EZO pH
sensor and two EZO PMP. The pumps dispense pH UP
and pH DOWN solutions into the sample and they are
triggered in accordance with the current pH reading.
The goal is to maintain the pH level of the sample
between 8 and 8.5
The sensors must be calibrated and switched to I2C
mode before using this code. The ability to send
commands to the sensors is not incorporated here.
After uploading the code to your arduino, open the serial
monitor, set the baud rate to 9600 and select "Carriage
return". The pH dosing system is now active.*/

#include <Ezo_i2c.h> //include the EZO I2C library


from https://github.com/Atlas-Scientific/Ezo_I2c_lib
#include <Wire.h> //include arduinos i2c library
Ezo_board PH = Ezo_board(99, "PH");
//creat a PH circuit object, whose address is 99 and name
is "PH"
Ezo_board PMP_UP = Ezo_board(103,
"PMP_UP"); //create a pump circuit object,
whose address is 103 and name is "PMP_UP". This
pump dispenses pH up solution.
Ezo_board PMP_DOWN = Ezo_board(104,
"PMP_DOWN"); //create a pump circuit object,
whose address is 104 and name is "PMP_DOWN". This
pump dispenses pH down solution.

bool reading_request_phase = true;


//selects our phase

uint32_t next_poll_time = 0;
//holds the next time we receive a response, in
milliseconds
const unsigned int response_delay = 1000;
//how long we wait to receive a response, in milliseconds

void setup() {
Wire.begin(); //start the I2C
Serial.begin(9600); //start the
serial communication to the computer
}
void loop() {
if (reading_request_phase) { //if
were in the phase where we ask for a reading

//send a read command. we use this command instead of


PH.send_cmd("R");
//to let the library know to parse the reading
PH.send_read_cmd();

next_poll_time = millis() + response_delay;


//set when the response will arrive
reading_request_phase = false; //switch
to the receiving phase
}
else { //if were in the
receiving phase
if (millis() >= next_poll_time) { //and its
time to get the response

receive_reading(PH); //get the


reading from the PH circuit
Serial.print(" ");

if (PH.get_last_received_reading() <= 8)
{ //test condition against pH reading
Serial.println("PH LEVEL LOW,PMP_UP = ON");
PMP_UP.send_cmd_with_num("d,", 0.5); //if
condition is true, send command to turn on pump (called
PMP_UP) and dispense pH up solution, in amounts of
0.5ml. Pump turns clockwise.
}
else {
PMP_UP.send_cmd("x"); //if
condition is false, send command to turn off pump
(called PMP_UP)
}

if (PH.get_last_received_reading() >= 8.5)


{ //test condition against pH reading
Serial.println("PH LEVEL HIGH,PMP_DOWN = ON");
PMP_DOWN.send_cmd_with_num("d,", -0.5);
//if condition is true, send command to turn on pump
(called PMP_DOWN) and dispense pH down solution,
in amounts of 0.5ml. Pump turns counter-clockwise.
}
else {
PMP_DOWN.send_cmd("x"); //if
condition is false, send command to turn off pump
(called PMP_DOWN)
}

Serial.println();
reading_request_phase = true; //switch
back to asking for readings
}
}
}

void receive_reading(Ezo_board &Sensor)


{ // function to decode the reading after the
read command was issued

Serial.print(Sensor.get_name()); Serial.print(": "); //


print the name of the circuit getting the reading

Sensor.receive_read_cmd(); //get
the response data and put it into the [Sensor].reading
variable if successful

switch (Sensor.get_error()) { //switch


case based on what the response code is.
case Ezo_board::SUCCESS:
Serial.print(Sensor.get_last_received_reading());
//the command was successful, print the reading
break;

case Ezo_board::FAIL:
Serial.print("Failed "); //means the
command has failed.
break;

case Ezo_board::NOT_READY:
Serial.print("Pending "); //the
command has not yet been finished calculating.
break;

case Ezo_board::NO_DATA:
Serial.print("No Data "); //the sensor
has no data to send.
break;
}
}
19) Arduino Simple Lap Counter for Swimming
COMPONENTS AND SUPPLIES
Magconn Developer Kit
× 1

Arduino Nano R3
× 1

USB Li-Po Battery Charger × 1


PCBA
Li-Po Battery 900mAh
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

Now the weather here is very hot because it is


summer. I went to the pool with my primary school
son to avoid the heat, and I saw people swimming
several times on the swimming track. How many laps
did they turn? When you learn to swim, count how
many turns you have made to measure your
momentum. But most people forget the count. There is
a wrist watch or a finger counter, but it is a little
uncomfortable when swimming. When swimming, it is
better not to do anything. I made an intuitively
waterproof lap-counter. Simply press it to go up once.
I would like to implement many functions, but step by
step.
Materials
There are some great conditions. The first is battery
use, the second is waterproof, and the third is
convenience. The battery should be rechargeable.
Because you do not have to open the case when it's
completely discharged. So I found connectors and
switches that are waterproof. The case recycled the
phone accessary case. I think that it was good to
recycle when I finished.
Assembling the Case
The lap-counter has a waterproof toggle switch and a
waterproof Magconn connector. I bought the Lithium-
Polymer battery and Lithium-rechargeable PCBA that
I had inexpensively. The back side of the Samsung
mobile phone case was machined to match the
Magconn connector, and the magnet was attached and
closed with epoxy. I added four more because I think
one magnet is not enough. The connector is closed
with epoxy and glue.
Build Circuit
I built a circuit on the breadboard and implemented
the behavior. The counter is fine. The four corners of
the switch are for height adjustment. After confirming
that it works well, I put it in the case and finished it
with silicon. When using glue gun, be careful because
case may melt at high temperature.
Waterproofing should be good. It was made better than
I thought. I was worried about the phone case, but the
recycle case became the key point.
Waterproof Test
I tried the waterproof test in the water of the pool.
There is a magnet on the back of the case, and if there
is an iron plate on the outside, it attaches
unconditionally. When there is no iron plate, a sucker
plate can be used.

SCHEMATICS
CODE

const byte numeral[10] = {


//ABCDEFG dp//
B11111100, //0
B01100000, //1
B11011010, //2
B11110010, //3
B01100110, //4
B10110110, //5
B00111110, //6
B11100000, //7
B11111110, //8
B11100110, //9
};

// dp, G, F, E, D, C, B, A
const int segmentPins[8] = { 9,8,7,6,5,4,3,2 };
const int nbrDigits = 2;
const int digitPins[nbrDigits] = { 12,13 };
const int buttonPin = 11;
int buttonState; // the current reading from the input pin
int lastButtonState = HIGH; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was
toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the
output flickers
int value = -1;

void setup()
{
for(int i=0; i<8; i++)
{
pinMode(segmentPins[i], OUTPUT);
}
for(int i=0; i<nbrDigits; i++)
{
pinMode(digitPins[i], OUTPUT);
digitalWrite(digitPins[i], 1);
}
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH); //
}

void loop()
{
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) { // reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;

if (buttonState == HIGH) {
value = value + 1;
}
}
}
lastButtonState = reading;
showNumber(value);
}

void showNumber(int number)


{
if(number == 0)
showDigit(0, nbrDigits-1);
else
{
for(int digit = nbrDigits-1; digit>=0; digit--)
{
if (number>0)
{
showDigit(number%10, digit);
number = number/10;
}
}
}
}

void showDigit(int number, int digit)


{
//boolean isBitSet;
digitalWrite(digitPins[digit],0); //1
for (int segment = 1; segment <8 ; segment++) //segment A ~ dp
{
boolean isBitSet = bitRead(numeral[number], segment); //byte
numeral[number] segment
digitalWrite(segmentPins[segment], isBitSet);
}
//isBitSet = !isBitSet
delay(5);
digitalWrite(digitPins[digit], 1);
}
20) Arduino Add Animated Lighting to Your Projects
COMPONENTS AND SUPPLIES

Arduino Nano R3
× 1

NeoPixel strip
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT

Simple DIY Animated Marquee Lighting


This a simple tutorial to add animated lighting to your
arcade cabinet or other projects. It can be used for
(back-)lighting marquees and many other purposes.
You will need an Arduino Nano (or compatible board),
a strip of NeoPixels, and 3 wires.

Short Setup
Hardware: Solder three wires from the Arduino Nano
to the NeoPixel strip: 5V, digital signal (I chose pin 2
on the Arduino) and ground.
Tip: Use a piece of heat shrink to tie the cables
together, especially the led strip (make sure the solder
connections are covered). This will prevent the solder
connections from coming loose.
Code: Set the number of LEDs of the connected strip
in the sketch code, upload it to the Arduino and test it.
I used a 'walking', flashing and pulsing animation in
the sketch, only using the color white. You can adjust
the code to do all sorts of animations and use many
colors. Or just use simple a backlight, whatever you
prefer.
The build: I cut 2 pieces of cardboard which fit snugly
in my cabinet. One piece is used as the background to
glue the neopixel strip on. The other strip is placed flat
behind the bottom of the marquee to prevent light
from the neopixels shining down directly. Afterward I
had to cut off some small edges to make it fit my
cabinet.
I put a few pieces of gaffa tape on the cardboard to
make them black. I glued the neopixel strip on the
cardboard and taped the wires and nano to the back of
the cardboard.
Put the 2 parts in the cabinet and attach a USB cable
from the nano to a 5V power source. In my cabinet it
is connected to a USB port of a Raspberry Pi.
Then place the stock marquee back or create your own
to customize your build. I created a simple one,
printed it on photo paper and cut it to fit the marquee.
Tip: The end result will be even better if you have
your design printed on film by a professional printing
company.
Libraries
The sketch needs one library:
Adafruit NeoPixel library
SCHEMATICS
CODE

/*
*************************************************************
*********
* Marquee lighting with Neopixels by ericBcreator
* simple script for lighting an (arcade) marquee
*************************************************************
*********
*
* components:
* - Neopixel strip
* - Arduino Nano
*
* This code is free for personal use, not for commercial purposes.
* Please leave this header intact.
*/

//
// include the libraries
//

#include <Adafruit_NeoPixel.h>

#define PIN
2
// define the pin the strip is
connected to

//
// setup variables and initialize the neopixel strip
//

int numOfLeds =
11;
// the numbers of leds on the strip
int minBrightness =
80;
// the minimum brightness of the pulsing and flashing (0-255)
int maxBrightness =
255;
// the maximum brightness of the pulsing and flashing (0-255)
int walkingLedsDelay =
250; //
the delay in ms for the walking leds
int flashDelay =
250;
// the delay in ms for the flashing leds
int numOfFlashLoops =
3;
// the number of times the leds flash
int numOfPulseLoops =
10;
// the number of times the leds puls from min to max
int pulseDelay =
20;
// the delay in ms when pulsing from min to max and
vice verse

Adafruit_NeoPixel strip = Adafruit_NeoPixel(numOfLeds, PIN);

//
// setup
//

void setup() {
strip.begin();
}

//
// main loop
//

void loop() {
walkingLeds();
// show the walking leds
flashLeds();
// flash the leds

for (int i = 0; i < numOfPulseLoops; i++) // puls the leds


pulseBrightness();
}

//
// functions
//

void walkingLeds() {
setLedColorsToZero();
strip.setBrightness(maxBrightness);
strip.show();

for (int x = numOfLeds; x > 0; x--) {


strip.setPixelColor(x, strip.Color(255, 255, 255));
strip.show();
delay(walkingLedsDelay );
strip.setPixelColor(x, 0);
strip.show();
}
}

void flashLeds() {
setLedColors();

for (int i = 0; i < numOfFlashLoops; i++) {


strip.setBrightness(maxBrightness);
strip.show();
delay(flashDelay );

strip.setBrightness(minBrightness);
strip.show();
delay(flashDelay );
}
}
void pulseBrightness() {
setLedColors();

for (int i = minBrightness; i < maxBrightness; i++) {


strip.setBrightness(i);
strip.show();
delay(pulseDelay);
}

for (int i = maxBrightness; i > minBrightness; i--) {


strip.setBrightness(i);
strip.show();
delay(pulseDelay);
}
}

void setLedColors() {
for (int x = 0; x < numOfLeds; x++)
strip.setPixelColor(x, strip.Color(255, 255, 255));
}

void setLedColorsToZero() {
for (int x = 0; x < numOfLeds; x++)
strip.setPixelColor(x, strip.Color(0, 0, 0));
}

21) Arduino 8X8 Matrix LED Snake Game


COMPONENTS AND SUPPLIES
PHPoC Shield for Arduino
× 1

Arduino UNO & Genuino


UNO
× 1

Adafruit 8x8 Bi-color LED × 1


Matrix

Jumper wires (generic)


× 1

ABOUT THIS PROJECT


It is the snake game on the 8x8 matrix LED by
smartphone motion.
When user tilts the smartphone to one of 4 directions,
the direction value is sent to Arduino through HTML5
WebSocket. Then the snake changes its direction.
SCHEMATICS

LED ----- PHPoC Shield


VCC ----- 5V
GND ----- GND
SDA ----- A4(SDA)
SCL ----- A5(SCL)
CODE

Arduino Source code

/***************************************************
This is a library for our I2C LED Backpacks

Designed specifically to work with the Adafruit LED Matrix backpacks


----> http://www.adafruit.com/products/872
----> http://www.adafruit.com/products/871
----> http://www.adafruit.com/products/870

These displays use I2C to communicate, 2 pins are required to


interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.


BSD license, all text above must be included in any redistribution
****************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_LEDBackpack.h>
#include "SPI.h"
#include "Phpoc.h"

PhpocServer server(80);

// LED face
static const uint8_t PROGMEM
smile_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
frown_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 };
// direction
const int TOP = 0;
const int RIGHT = 1;
const int BOTTOM = 2;
const int LEFT = 3;

// Snake
const int MAX_SNAKE_LENGTH = 15;

// Variables
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix(); // Display
int direction = TOP; // direction of movement
int snakeX[MAX_SNAKE_LENGTH]; // X-coordinates of
snake
int snakeY[MAX_SNAKE_LENGTH]; // Y-coordinates of
snake
int snakeLength = 1; // nr of parts of snake
unsigned long prevTime = 0; // for gamedelay (ms)
unsigned long delayTime = 500; // Game step in ms

int fruitX, fruitY;


unsigned long fruitPrevTime = 0;
unsigned long fruitBlinkTime = 1000/250;
int fruitLed = LED_RED;
int matrixColor;

void setup(){
Serial.begin(9600);
while(!Serial)
;

Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
server.beginWebSocket("snake");

Serial.print("WebSocket server address : ");


Serial.println(Phpoc.localIP());

Serial.println("Game is started.");
randomSeed(analogRead(0));
// Init led matrix
matrix.begin(0x70);
matrix.setRotation(3);

// init snake
snakeX[0] = 4;
snakeY[0] = 7;
for(int i=1; i<MAX_SNAKE_LENGTH; i++)
snakeX[i] = snakeY[i] = -1;

makeFruit();

printString("S");
}

void loop(){
checkButtons();

unsigned long currentTime = millis();


if(currentTime - prevTime >= delayTime)
{
nextstep();
prevTime = currentTime;
}

draw();
}

void checkButtons(){

// wait for a new client:


PhpocClient client = server.available();

if (client)
{
if (client.available() > 0)
{
// read the bytes incoming from the client:
char thisChar = client.read();

if(thisChar == '0')
direction = TOP;
if(thisChar == '1')
direction = LEFT;
if(thisChar == '2')
direction = RIGHT;
if(thisChar == '3')
direction = BOTTOM;
}
}
}

void draw(){
matrix.clear();
drawSnake();
drawFruit();
matrix.writeDisplay();
}

void drawSnake(){
for(int i=0; i<snakeLength; i++)
matrix.drawPixel(snakeX[i], snakeY[i], LED_GREEN);
}

void drawFruit(){
if(inPlayField(fruitX, fruitY)){
unsigned long currenttime = millis();
if(currenttime - fruitPrevTime >= fruitBlinkTime)
{
fruitLed = (fruitLed == LED_RED) ? LED_OFF : LED_RED;
fruitPrevTime = currenttime;
}
matrix.drawPixel(fruitX, fruitY, fruitLed);
}
}

boolean inPlayField(int x, int y){


return (x>=0) && (x<8) && (y>=0) && (y<8);
}

void nextstep(){
for(int i = snakeLength; i > 0; i--)
{
if((direction == RIGHT) && (snakeX[0]-snakeLength == 7))
snakeX[0] = -1;
else if((direction == LEFT) && (snakeX[0]+ snakeLength == 0))
snakeX[0] = 8;
else
snakeX[i] = snakeX[i-1];

if((direction == TOP) && (snakeY[0]+snakeLength == 0))


snakeY[0] = 8;
else if((direction == BOTTOM) && (snakeY[0]-snakeLength == 7))
snakeY[0] = -1;
else
snakeY[i] = snakeY[i-1];
}

switch(direction)
{
case TOP:
snakeY[0] = snakeY[0]-1;
break;
case RIGHT:
snakeX[0] = snakeX[0]+1;
break;
case BOTTOM:
snakeY[0] = snakeY[0]+1;
break;
case LEFT:
snakeX[0]=snakeX[0]-1;
break;
}

if((snakeX[0] == fruitX) && (snakeY[0] == fruitY))


{
snakeLength++;
if(snakeLength < MAX_SNAKE_LENGTH)
makeFruit();
else
fruitX = fruitY = -1;

}
snakeCheck();
}

void makeFruit(){
int x, y;
x = random(0, 8);
y = random(0, 8);
while(isPartOfSnake(x, y)){
x = random(0, 8);
y = random(0, 8);
}
fruitX = x;
fruitY = y;
}

boolean isPartOfSnake(int x, int y){


for(int i=0; i<snakeLength-1; i++)
{
if((x == snakeX[i]) && (y == snakeY[i]))
return true;
}
return false;
}

void snakeCheck(){
for(int i=1; i<snakeLength; i++)
{
// snake touches itself
if((snakeX[0] == snakeX[i]) && (snakeY[0] == snakeY[i]))
userLose();
}
if (snakeLength == MAX_SNAKE_LENGTH)
userWin();
}

void userLose(){
Serial.println("Game Over");
printString("O");

matrix.clear();
matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_RED);
matrix.writeDisplay();
delay(1000);

snakeLength = 1;
setup();
loop();
}

void userWin(){
Serial.println("You Win");
printString("W");

matrix.clear();
matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_GREEN);
matrix.writeDisplay();
delay(1000);

snakeLength = 1;
setup();
loop();
}

void printString(String str){


String matrixComment;

matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely


matrix.setTextSize(1);

if (str == "O")
{
matrixComment = "Game Over!";
matrixColor = LED_RED;
}
else if (str == "W")
{
matrixComment = "You Win!";
matrixColor = LED_GREEN;
}
else if (str == "S")
{
matrixComment = "Go!";
matrixColor = LED_YELLOW;
}
else
matrixColor = LED_YELLOW;

matrix.setTextColor(matrixColor);

for (int8_t x=7; x>=-60; x--)


{
matrix.clear();
matrix.setCursor(x,0);
matrix.print(matrixComment);
matrix.writeDisplay();
delay(70);
}
}

PHPoC Shield source code

<!DOCTYPE html>
<html>
<head>
<title>PHPoC Shield - Snake Game</title>
<meta name="viewport" content="width=device-width,
initial-scale=0.7, maximum-scale=0.7">
<style>
body { font-family: verdana, Helvetica, Arial, sans-serif,
gulim; font-weight: bold; text-align: center; }
h1 { font-size: 25pt; }
h2 { font-size: 15pt; }
#remote { margin:0 auto; width: 500px; background:
#333; border-radius: 2%; }
.direct {
display: inline-block; width: 100px; height: 100px;
font-size: 50px; color: white; line-height: 90px;
background: #eee; margin: 8px; border-radius: 10%;
text-align: center; font-weight: bold;
margin: 10px 60px;
}
</style>
<script>
var ws;
var button;

function init()
{
if(ws == null)
{
ws = new WebSocket("ws://<?echo
_SERVER("HTTP_HOST")?>/snake", "text.phpoc");
document.getElementById("ws_state").innerHTML =
"CONNECTING";

ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
}
else
ws.close();
}
function connect_onclick()
{
if(ws == null)
{
var ws_host_addr = "<?echo
_SERVER("HTTP_HOST")?>";
//var debug = document.getElementById("debug");

if((navigator.platform.indexOf("Win") != -1) &&


(ws_host_addr.charAt(0) == "["))
{
// network resource identifier to UNC path name
conversion
ws_host_addr = ws_host_addr.replace(/[\[\]]/g, '');
ws_host_addr = ws_host_addr.replace(/:/g, "-");
ws_host_addr += ".ipv6-literal.net";
}

//debug.innerHTML = "<br>" + navigator.platform + " "


+ ws_host_addr;
ws = new WebSocket("ws://" + ws_host_addr +
"/snake", "text.phpoc");

document.getElementById("ws_state").innerHTML =
"CONNECTING";

ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
}
else
ws.close();
}
function ws_onopen()
{
document.getElementById("ws_state").innerHTML = "
<font color='blue'>CONNECTED</font>";
document.getElementById("bt_connect").innerHTML =
"Disconnect";
}
function ws_onclose()
{
document.getElementById("ws_state").innerHTML = "
<font color='gray'>CLOSED</font>";
document.getElementById("bt_connect").innerHTML =
"Connect";

ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
}
function ws_onmessage(e_msg)
{
e_msg = e_msg || window.event; // MessageEvent

alert("msg : " + e_msg.data);


}

var beta = 0;
var gamma = 0;
var resolution = 2;

if (window.DeviceOrientationEvent)
{
window.addEventListener('deviceorientation',
orientationUpdate, true);
}
function orientationUpdate(event)
{

if(Math.abs((event.beta - beta)) > resolution)


beta = event.beta;

if(Math.abs((event.gamma - gamma)) > resolution)


gamma = event.gamma;

//var debug = document.getElementById("debug");


//debug.innerHTML = beta + "/" + gamma;

for (i=0; i<4; i++)


{
button = document.getElementById(i);
button.style.backgroundColor = "grey";
}

if (beta < 0) // top


{
button = document.getElementById(0);
button.style.backgroundColor = "#E9FF26";
ws.send("0");
}
else if (gamma < -35 && beta < 50) // left
{
button = document.getElementById(1);
button.style.backgroundColor = "#E9FF26";
ws.send("1");
}
else if (gamma > 35 && beta < 50) // right
{
button = document.getElementById(2);
button.style.backgroundColor = "#E9FF26";
ws.send("2");
}
else if (beta > 60) // bottom
{
button = document.getElementById(3);
button.style.backgroundColor = "#E9FF26";
ws.send("3");
}

}
window.onload = init;
</script>
</head>

<body>
<h1>Snake Game</h1>
<br /><br />
<div id="remote">
<div class="direct" id="0">↑</div><br />
<div class="direct" id="1">←</div>
<div class="direct" id="2">→</div><br />
<div class="direct" id="3">↓</div>
</div>
<br /><br />
<h2>WebSocket <font id="ws_state"
color="gray">CLOSED</font></h2>
<button id="bt_connect" type="button"
onclick="connect_onclick();">Connect</button>
<span id="debug"></span>
</body>
</html>
22) Arduino Eco Smart Container
COMPONENTS AND SUPPLIES

Arduino 101 & Genuino 101


× 1

SparkFun Inventor's Kit for


Arduino 101
× 1

Raspberry Pi Zero Wireless


× 1

DHT22 Temperature Sensor


× 1

Seeed Grove starter kit plus for


Intel Edison
× 1

Jumper wires (generic) × 1


Ultrasonic Sensor - HC-SR04
(Generic)
× 1

SparkFun Soil Moisture Sensor


(with Screw Terminals)
× 1

Breadboard (generic)
× 1

Li-Ion Battery 1000mAh


× 1

USB-A to B Cable
× 1

USB-A to Micro-USB Cable × 1


NECESSARY TOOLS AND MACHINES
Hot glue gun (generic)
APPS AND ONLINE SERVICES
Blynk

Arduino IDE

ABOUT THIS PROJECT


Material
1. SparkFun Inventor's Kit for Arduino 101
SparkFun Inventor's Kit for Arduino 101
This material was given to me by the sponsors of the
contest, I thank you for the trust and support. This
material contains the plate you use and the
temperature sensor TMP36 that I use to measure the
temperature.
To test the circuits you were using, use the Arduino
and Breadboard Holder. The arduino 101.
2. Grove Shield
This shield is perfect for prototyping and connecting
components exclusive to the Grove platform.
3. Grove LCD I2C
This screen can be connected through the I2C port of
the Arduino 101 and you can change the color of the
lighting and it has a very nice design.
4. Raspberry pi zero w

This board has all the advantages of raspberry pi zero


but with the addition of bluetooth 4.0 connectivity and
wi-fi, use it to receive arduino sensor values by means
of bluetooth. Programming in Node Js was a very
enjoyable, intuitive and effective experience.
5. DHT22
This digital sensor of humidity and temperature is
very used and has good results, this one uses it to
measure the temperature and humidity near the central
device that is the raspberry pi zero w.
6. Ultrasonic sensor
This sensor I used to measure the level of trash in the
trash can, had good results, but probably in an update
can be changed by a sensor or infrared sensor in my
opinion seem more reliable but in my country it is
difficult to achieve components as sensors.
7. Moisture sensor
This sensor used it to measure the level of humidity in
the earth, any high reading of humidity means that
there could be rain or some flood and that could be a
problem for the garbage of that place, sends a warning
to the application.
8. Solar battery bank
Any project needs power, my prototype I put this
power bank of 12000mAh, which also recharges solar,
ideally would have a panel built especially for my
prototype. But this device worked great. I used 2 for
raspberry pi zero w and arduino 101 in my smart trash
can.
9. Arduino 101 6-Axis Acelerometer and Gyroscope
To know if my trash can had fallen, or someone threw
it on the floor. Use the accelerometer and gyroscope
included in the Arduino 101. It was easy to implement
and send the data to the central base.
Results
In the physical aspect of the prototype I will show
some images and explain the why of each thing.
Below we have the top of the trash can that has the
LCD grove that has a nice message for people who use
it and leave their waste and also has as information the
time and a word, "ON" which means that the system is
Connected to the central unit which is the raspberry pi
zero wy "OFF" means that it is disconnected.

Below is the finished prototype, on the outside only


the LCD is visible on the top and on the back you can
see the power bank with its solar panel, so this device
is autonomous and sustainable with the environment.

To prove that the arduino data was reaching the


raspberry pi zero, I made the latter by programming in
node JS, print the value of each sensor per console in
Putty and below my results.
To implement the SMS notifications for my project I
had to investigate on the internet a lot and everything I
gathered in the tutorial in which I leave the link below.
https://www.hackster.io/alexis-santiago-allende/sms-
alerts-for-arduino-101-ble-e7184d
Also to connect arduino 101 with the raspberry pi zero
w by bluetooth of low energy carry out the following
tutorial, in which I leave to information that I found
and as I did the process. In this final project was to
unite these two previous examples and make slight
modifications to obtain the desired operation.
https://www.hackster.io/alexis-santiago-
allende/arduino-101-connects-with-raspberry-pi-zero-
w-63adc0
Blynk App
Below you can see how the application looks
aesthetically, at the top of the application you can see
small boxes that are widgets, two of which enable
notifications, one of them is the one that activates the
events of the Blynk application and the Last is a bin
viewer at the moment. In the central part you can see 4
very beautiful displays of temperature and humidity.
One pair is from the arduino 101 and the other are
from the raspberry pi zero w, with my prototype you
can add more visualization widgets and more sensors
but only use the ones that had available.
In the lower part you can see the trash level display
next to 2 general purpose buttons. That could be used
to control any item at a distance as lights from the
central unit. The use of this hardware together with
Blynk gives many possibilities.
Notifications examples:
There are two types of notifications implemented,
notifications specific to the application and those that
are through the Twilio SMS service. Here below we
have the temperature notification, when the
temperature is higher than a threshold, this sends a
notification. In the project notification is also given
when the trash can is full.
Temperature notification
Notifications are also given when the central device is
disconnected or there is a connection failure.
Offline notifications
Apart from the notifications of the app, under the
same cases, or if the previous notifications do not
work, we have the notifications by SMS that in my
opinion are more effective, below I leave the example
of when the trash can is full.
SMS notification

SCHEMATICS
CODE

Main code arduino

#include <CurieBLE.h>
#include "CurieIMU.h"
#include <Wire.h>
#include "rgb_lcd.h"
#include <CurieTime.h>

BLEPeripheral blePeripheral;//BLE Peripheral Device (Arduino Device)


BLEService demo111("19b10000-e8f2-537e4f6c-d104768a1214"); // BLE
demo111 Service
// BLE sensor rate Characteristic"
BLEUnsignedIntCharacteristic sensor1("19b10001-e8f2-537e4f6c-
d104768a1214", BLERead | BLENotify);
// BLE sensor rate Characteristic"
BLEUnsignedIntCharacteristic sensor2("19b10002-e8f2-537e4f6c-
d104768a1214", BLERead | BLENotify);
// BLE sensor rate Characteristic"
BLEUnsignedIntCharacteristic sensor3("19b10003-e8f2-537e4f6c-
d104768a1214", BLERead | BLENotify);
// BLE sensor rate Characteristic"
BLEUnsignedIntCharacteristic sensor4("19b10004-e8f2-537e4f6c-
d104768a1214", BLERead | BLENotify);
//Ble palabra sensor Characteristic
BLECharacteristic palabra("19b10005-e8f2-537e4f6c-d104768a1214",
BLERead | BLENotify,10);
// BLE demo111 buttons Characteristic - custom 128-bit UUID, read and
writable by central
BLEUnsignedCharCharacteristic buttons("19b10006-e8f2-537e4f6c-
d104768a1214", BLERead | BLEWrite);
rgb_lcd lcd;
const int colorR = 198;
const int colorG = 78;
const int colorB = 25;
int lastOrientation = - 1; // previous orientation (for comparison)
long previousMillis = 0; // last time the sensor was checked, in ms
const int green = 13; // pin to use for the green light
const int red = 11;// pin to use for the red light
boolean a = LOW, b = LOW; //Control variables
int temp=0;
long distancia;
long tiempo;
int orientation;
int valor=0,nivel=0,ndistancia;

void setup() {
Serial.begin(9600);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.setRGB(colorR, colorG, colorB);
// Print a message to the LCD.
setTime(16, 56, 24, 3, 07, 2017);
lcd.print("Have a nice day!");
lcd.setCursor(12, 1);
lcd.print("Off");
pinMode(green, OUTPUT); // use the LED on pin 13 as an output
pinMode(red, OUTPUT);
pinMode(9, OUTPUT); /*activación del pin 9 como salida: para el pulso
ultrasónico*/
pinMode(8, INPUT);
CurieIMU.begin();
CurieIMU.setAccelerometerRange(2);
// set the local name peripheral advertises
blePeripheral.setLocalName("Demo111");
// set the UUID for the service this peripheral advertises
blePeripheral.setAdvertisedServiceUuid(demo111.uuid());

// add service and characteristic


blePeripheral.addAttribute(demo111);
blePeripheral.addAttribute(buttons);
blePeripheral.addAttribute(sensor1);
blePeripheral.addAttribute(sensor2);
blePeripheral.addAttribute(sensor3);
blePeripheral.addAttribute(sensor4);
blePeripheral.addAttribute(palabra);

// assign event handlers for connected, disconnected to peripheral


blePeripheral.setEventHandler(BLEConnected,
blePeripheralConnectHandler);
blePeripheral.setEventHandler(BLEDisconnected,
blePeripheralDisconnectHandler);

// assign event handlers for characteristic


buttons.setEventHandler(BLEWritten, switchCharacteristicWritten);

// sensors.setEventHandler(BLEWritten, switchCharacteristicWritten);
// set an initial value for the characteristic
buttons.setValue(0);
sensor1.setValue(0);
sensor2.setValue(0);
sensor3.setValue(0);
sensor4.setValue(0);
// advertise the service
blePeripheral.begin();
Serial.println(("Bluetooth device active, waiting for connections..."));
}

void loop() {
// poll peripheral
blePeripheral.poll();
digitalWrite(9,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);
digitalWrite(9, HIGH); /* envío del pulso ultrasónico*/
delayMicroseconds(10);
tiempo=pulseIn(8, HIGH); /* Función para medir la longitud del pulso
entrante. Mide el tiempo que transcurrido entre el envío
del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que
el pin 12 empieza a recibir el rebote, HIGH, hasta que
deja de hacerlo, LOW, la longitud del pulso entrante*/
distancia= int(0.017*tiempo); /*fórmula para calcular la distancia
obteniendo un valor entero*/

char clockTime[8];
//use sprintf to create a time string of the hour, minte and seconds
sprintf(clockTime, "%02d:%02d:%02d", hour(), minute(), second());
//set cursor to column 0, row 0
lcd.setCursor(2, 1);
//print the date string over lcd
lcd.print(clockTime);

long currentMillis = millis();


// if 1s have passed, check the sensor:
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
updateSensor();
}

orientation = - 1; // the board's orientation


String orientationString; // string for printing description of orientation

// read accelerometer:
int x = CurieIMU.readAccelerometer(X_AXIS);
int y = CurieIMU.readAccelerometer(Y_AXIS);
int z = CurieIMU.readAccelerometer(Z_AXIS);

// calculate the absolute values, to determine the largest


int absX = abs(x);
int absY = abs(y);
int absZ = abs(z);

if ( (absZ > absX) && (absZ > absY)) {


// base orientation on Z
if (z > 0) {
orientationString = "up";
orientation = 0;
} else {
orientationString = "down";
orientation = 1;
}
} else if ( (absY > absX) && (absY > absZ)) {
// base orientation on Y
if (y > 0) {
orientationString = "digital pins up";
orientation = 2;
} else {
orientationString = "analog pins up";
orientation = 3;
}
} else {
// base orientation on X
if (x < 0) {
orientationString = "connector up";
orientation = 4;
} else {
orientationString = "connector down";
orientation = 5;
}
}

// if the orientation has changed, print out a description:


if (orientation != lastOrientation) {
Serial.println(orientationString);
lastOrientation = orientation;
}

void blePeripheralConnectHandler(BLECentral& central) {


// central connected event handler
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Have a nice day!");
Serial.print("Connected event, central: ");
Serial.println(central.address());
lcd.setCursor(12, 1);
lcd.print("On");
}

void blePeripheralDisconnectHandler(BLECentral& central) {


// central disconnected event handler
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Have a nice day!");
Serial.print("Disconnected event, central: ");
Serial.println(central.address());
lcd.setCursor(12, 1);
lcd.print("Off");
}

void switchCharacteristicWritten(BLECentral& central,


BLECharacteristic& characteristic) {
// central wrote new value to characteristic, update LED
Serial.print("Characteristic event, written: ");
Serial.print(buttons.value());
if (buttons.value() == 1 && a == LOW) { // 1 in ASCII

Serial.print("LED on");
digitalWrite(green, HIGH); // will turn the LED on
a = HIGH;
} else if (buttons.value() == 1 && a == HIGH) { //when 1 was read again
(second time)

Serial.println("LED off");
digitalWrite(green, LOW); // will turn the LED off
a = LOW;
}
else if (buttons.value() == 2 && b == LOW) { // 1 in ASCII
Serial.print("LED on");
digitalWrite(red, HIGH); // will turn the LED on
b = HIGH;
} else if (buttons.value() == 2 && b == HIGH) { //when 1 was read again
(second time)

Serial.println("LED off");
digitalWrite(red, LOW); // will turn the LED off
b = LOW;
}

void updateSensor() {
temp=analogRead(A0);//dht.readTemperature();//read temperature
valor=analogRead(A1);
nivel = map(valor, 0, 1023, 100, 0);
ndistancia = map(distancia, 38, 2, 0, 100);
float sensorLevel = temp*(3.3/1023);
int temp1=(sensorLevel-0.5)*100;
sensor1.setValue(temp1);//send temperature value
sensor2.setValue(distancia);//send distance value
sensor3.setValue(orientation);//send orientation value
sensor4.setValue(nivel);//send percentage of hummidity value
Serial.println(temp1);
Serial.println(distancia);
Serial.println(orientation);
Serial.println(nivel);

}
Main code Node JS

//Blynk
var Blynk = require('blynk-library');

var AUTH = 'adea86da8f774157b6a4997a6ed18a08';

var blynk = new Blynk.Blynk(AUTH);


var v1 = new blynk.VirtualPin(1);
var v9 = new blynk.VirtualPin(9);
var v8 = new blynk.VirtualPin(8);
var v7 = new blynk.VirtualPin(7);
var v6 = new blynk.VirtualPin(6);
var v5 = new blynk.VirtualPin(5);
var v4 = new blynk.VirtualPin(4);
var v3 = new blynk.VirtualPin(3);

//Bluetooth low energy


var noble = require('noble');

// Search only for the Service UUID of the device


(remove dashes)
var serviceUuids =
['19b10000e8f2537e4f6cd104768a1214'];

// Search only for the led charateristic


var characteristicUuids =
['19b10001e8f2537e4f6cd104768a1214','19b10002e8f25
37e4f6cd104768a1214','19b10003e8f2537e4f6cd104768
a1214','19b10004e8f2537e4f6cd104768a1214','19b1000
5e8f2537e4f6cd104768a1214','19b10006e8f2537e4f6cd
104768a1214'];

var sensor1=0;
var sensor2=0;
var sensor3=0;
var sensor4=0;
var temperatura=0;
var humedad=0;
var boton=0;
var contador1=0,contador2=0,contador3=0,contador4=0;

//Twilio
const twilio = require('twilio')
var accountSid =
'AC4c3a664e0475a08a4e0fdbd016555a70';
var authToken = '22ee6e5fe596967997a2d1a57d6d73eb';

const phone = new twilio(accountSid, authToken);

const sendMessage = () => {


phone.messages.create({
to: "+526462378678",
from: "+12818266123 ",
body: 'WARNING!!!!!! take care, please review your
Blynk app now!!!!!',
})
}
//Reading DHT22
var sensor = require('node-dht-sensor');
//Final
v1.on('write', function(param) {
boton=param[0];

});

v9.on('read', function() {
v9.write(new Date().getSeconds());
});

v8.on('read', function() {
v8.write(sensor1);
});

v7.on('read', function() {
v7.write(humedad);
});

v6.on('read', function() {
v6.write(temperatura);
});

v5.on('read', function() {
v5.write(sensor2);
});
v4.on('read', function() {
v4.write(sensor3);
});

v4.on('read', function() {
v4.write(sensor4);
});

// start scanning when bluetooth is powered on


noble.on('stateChange', function(state) {
if (state === 'poweredOn') {
noble.startScanning(serviceUuids);
} else {
noble.stopScanning();
}
});

//Reading sensor
setInterval(function() {
sensor.read(22, 21, function(err, temperature, humidity)
{
if (!err) {
temperatura=temperature.toFixed(1);
humedad= humidity.toFixed(1);

}
});
}, 1000);

// Search for BLE peripherals


noble.on('discover', function(peripheral) {
peripheral.connect(function(error) {
console.log('connected to peripheral: ' +
peripheral.uuid);
// Only discover the service we specified above
peripheral.discoverServices(serviceUuids,
function(error, services) {
var service = services[0];
console.log('discovered service');

service.discoverCharacteristics(characteristicUuids,
function(error, characteristics) {
console.log('discovered characteristics');
// Assign Characteristic
var sensor1Characteristic = characteristics[1];
var sensor2Characteristic = characteristics[2];
var sensor3Characteristic = characteristics[3];
var sensor4Characteristic = characteristics[4];
//var botonCharacteristic = characteristics[4];

setInterval(function() {

sensor1Characteristic.read(function(error, data) {
// data is a buffer
console.log('Temperature is: ' + data.readUInt8(0));
sensor1=data.readUInt8(0);
if (data.readUInt8(0)>=32 && contador1===0) {
sendMessage();
contador1=1;
}
else if(data.readUInt8(0)<=30 && contador1==1){
contador1=0;

});

sensor2Characteristic.read(function(error, data) {
// data is a buffer
console.log('Trash percent is: ' + data.readUInt8(0));
sensor2=data.readUInt8(0);
if (data.readUInt8(0)<=4 && contador2===0) {
sendMessage();
contador2=1;
}
else if(data.readUInt8(0)>=30 && contador2==1){
contador2=0;

}
});
sensor3Characteristic.read(function(error, data) {
// data is a buffer
console.log('Orientation: ' + data.readUInt8(0));
sensor3=data.readUInt8(0);
if (data.readUInt8(0)!=2 && contador3===0) {
sendMessage();
contador3=1;
}
else if(data.readUInt8(0)==2 && contador3==1){
contador3=0;

}
});

sensor4Characteristic.read(function(error, data) {
// data is a buffer
console.log('Humidity: ' + data.readUInt8(0));
sensor4=data.readUInt8(0);
if (data.readUInt8(0)>=90 && contador4===0) {
sendMessage();
contador4=1;
}
else if(data.readUInt8(0)<=30 && contador4==1){
contador4=0;
}
});

}, 1000);

// var bufferToSend = new Buffer(1);


// bufferToSend.writeUInt8(boton);
// console.log(bufferToSend);
// botonCharacteristic.write(bufferToSend, false);
// setInterval(function() {
//bufferToSend.writeUInt8(1); // you can pass this any
integer, we just do this to alternate 0/1
// botonCharacteristic.write(bufferToSend, false);
// }, 1000);
});
});
});
});
23) Arduino Without External Clock Ctystal on
Atmega328

COMPONENTS AND SUPPLIES


Arduino UNO & Genuino UNO
To program the ATmega chip
× 1
on the breadboard. You can use
FTDI Breakout Board also.
Microchip Atmega328
× 1
Breadboard (generic) × 1

Jumper wires (generic)


× 1

SparkFun FTDI 232RL USB to


Serial Converter
× 1
If not using Arduino Uno, then,
use this.
Capacitor 100 nF
To be used if using FTDI USB × 1
to Serial Breakout.
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT


An Arduino consists of many components like: a
linear regulator, USB to Serial microcontroller, debug
LED, power LED, reset button, RX & TX LED,
crystal oscillator, etc. But a minimal circuit can have
just the brain of the Arduino UNO, that is, an
ATmega328p microcontroller (Reducing Arduino
Power Consumption). You can assume this one is an
extended version of that project.
Making a Minimal Arduino UNO on a Breadboard
Most people are successful in making Arduino with
minimal circuitry, but use the 16 MHz crystal. We can
remove that, too, along with 22 pF capacitors. You can
configure the ATmega328 to use its internal 8 MHz
RC oscillator as a clock source.
Install Support for Hardware Configuration
Download this hardware configuration
archive: breadboard-1-6-x.zip, Breadboard1-5-
x.zip or Breadboard1-0-x.zip depending on
which IDE you use.
Create a "hardware" sub-folder in your Arduino
sketchbook folder (whose location you can find
in the Arduino preferences dialog). If you've
previously installed support for additional
hardware configuration, you may already have a
"hardware" folder in your sketchbook.
Move the breadboard folder from the zip archive
to the "hardware" folder of your Arduino
sketchbook.
Restart the Arduino software.
You should see "ATmega328 on a breadboard (8
MHz internal clock)" in the Tools > Board menu.
Once you've done this, you can burn the bootloader
and upload programs onto your ATmega328.
Putting Stuff on Breadboard
Get all the stuff listed above. Moreover, keep a pin
mapping of the ATmega328P handy while making the
circuit.
ATmega328p pin mapping.
Using ATmega Without UNO Bootloader
First of all, we need to burn the bootloader to the
ATmega chip if you bought a blank microcontroller
having no bootloader, so that it can be a
programmable entity.
Refer to the schematics and place the ATmega
chip in the breadboard.
Open the ArduinoISP firmware (in Examples) to
your Arduino board.
Select the items in the Tools > Board and Serial
Port menus that correspond to the board you are
using as the programmer (not the board being
programmed).
Upload the ArduinoISP sketch.
Select the item in the Tools > Board menu and be
sure to select "ATmega328 on a breadboard
(8MHz internal clock)" when burning the
bootloader.
Select the Arduino as ISP in the Tools >
Programmer menu.
Use the Burn Boot-loader command in
the Tools menu.
Skip step 2 if you have done step 1.
2. Using ATmega with UNO boot-loader
If the ATmega is already boot-loaded, then just put it
in the breadboard and we can proceed programming
the ATmega328p microcontroller.
3. Programming the ATmega chip (using other
Arduino)
Remove the microcontroller of the Arduino you
are using as the programmer.
Refer to the schematics and pin mapping and
connect the Rx and Tx of programmer
Arduino to Tx and Rx of the breadboard
Arduino respectively.
Connect RESET of programmer
Arduino to RESET of breadboard Arduino.
Connect GND and VCC of breadboard
Arduino to GND and VCC on programmer
Arduino.
Select the item in the Tools > Board menu and be
sure to select "ATmega328 on a breadboard
(8MHz internal clock)".
Check the port and click on "upload".
Plug out the connections and now you can power it
with a battery for months depending on the kind of
project.
4. Programming the ATmega chip (using FTDI USB to
Serial Adapter)
Curious what all the pin outs are for on the FT232RL
breakout board? Simply flip it over! In this situation
I'll be using VCC (to supply 5V from the USB port to
your board), GND, TXD, and RXD. [Refer to
schematics]
FTDI 232RL Breakout board pinouts.
This board comes without the headers when
bought from market. So, solder the male header
and plug it in the breadboard.
Connect Rx of ATmega chip to Tx of board
and Tx of ATmega chip to Rx of the board.
Connect Vcc and GND to the power rails on the
breadboard.
Plug the USB mini type - B and connect it with
your computer and upload the sketch using the
Arduino IDE but always remember to select
"ATmega328 on a breadboard (8MHz internal
clock)". It will take power from the USB but
after disconnecting the USB, you can plug the
battery terminals to the power rails of
breadboard.
And the Arduino is ready.

SCHEMATICS

Using an Arduino board to burn the bootloader onto


an ATmega on a breadboard (w/o an external clock)
Uploading sketches to an ATmega on a
breadboard(using another Arduino).
Uploading sketches to an ATmega on a
breadboard(using FTDI 232RL Driver)
Ignore the capacitors(except 10nF cap), resistors and
the clock crystal.
CODE

// This sketch turns the Arduino into a AVRISP


// using the following arduino pins:
//
// Pin 10 is used to reset the target microcontroller.
//
// By default, the hardware SPI pins MISO, MOSI and
SCK pins are used
// to communicate with the target. On all Arduinos, these
pins can be found
// on the ICSP/SPI header:
//
// MISO . . 5V (!) Avoid this pin on Due, Zero...
// SCK . . MOSI
// . . GND
//
// On some Arduinos (Uno,...), pins MOSI, MISO and
SCK are the same pins
// as digital pin 11, 12 and 13, respectively. That is why
many tutorials
// instruct you to hook up the target to these pins. If you
find this wiring
// more practical, have a define
USE_OLD_STYLE_WIRING. This will work even
// even when not using an Uno. (On an Uno this is not
needed).
//
// Alternatively you can use any other digital pin by
configuring software ('BitBanged')
// SPI and having appropriate defines for PIN_MOSI,
PIN_MISO and PIN_SCK.
//
// IMPORTANT: When using an Arduino that is not 5V
tolerant (Due, Zero, ...)
// as the programmer, make sure to not expose any of the
programmer's pins to 5V.
// A simple way to accomplish this is to power the
complete system (programmer
// and target) at 3V3.
//
// Put an LED (with resistor) on the following pins:
// 9: Heartbeat - shows the programmer is running
// 8: Error - Lights up if something goes wrong (use
red if that makes sense)
// 7: Programming - In communication with the slave
//

#include "Arduino.h"
#undef SERIAL

#define PROG_FLICKER true

// Configure SPI clock (in Hz).


// E.g. for an attiny @128 kHz: the datasheet states that
both the high
// and low spi clock pulse must be > 2 cpu cycles, so take
3 cycles i.e.
// divide target f_cpu by 6:
// #define SPI_CLOCK (128000/6)
//
// A clock slow enough for an attiny85 @ 1MHz, is a
reasonable default:

#define SPI_CLOCK (1000000/6)


// Select hardware or software SPI, depending on SPI
clock.
// Currently only for AVR, for other archs (Due, Zero,...),
// hardware SPI is probably too fast anyway.

#if defined(ARDUINO_ARCH_AVR)

#if SPI_CLOCK > (F_CPU / 128)


#define USE_HARDWARE_SPI
#endif

#endif

// Configure which pins to use:

// The standard pin configuration.


#ifndef ARDUINO_HOODLOADER2

#define RESET 10 // Use pin 10 to reset the target


rather than SS
#define LED_HB 9
#define LED_ERR 8
#define LED_PMODE 7

// Uncomment following line to use the old Uno style


wiring
// (using pin 11, 12 and 13 instead of the SPI header) on
Leonardo, Due...

// #define USE_OLD_STYLE_WIRING

#ifdef USE_OLD_STYLE_WIRING

#define PIN_MOSI 11
#define PIN_MISO 12
#define PIN_SCK 13

#endif

// HOODLOADER2 means running sketches on the


atmega16u2
// serial converter chips on Uno or Mega boards.
// We must use pins that are broken out:
#else

#define RESET 4
#define LED_HB 7
#define LED_ERR 6
#define LED_PMODE 5

#endif

// By default, use hardware SPI pins:


#ifndef PIN_MOSI
#define PIN_MOSI MOSI
#endif

#ifndef PIN_MISO
#define PIN_MISO MISO
#endif

#ifndef PIN_SCK
#define PIN_SCK SCK
#endif

// Force bitbanged SPI if not using the hardware SPI


pins:
#if (PIN_MISO != MISO) || (PIN_MOSI != MOSI) ||
(PIN_SCK != SCK)
#undef USE_HARDWARE_SPI
#endif

// Configure the serial port to use.


//
// Prefer the USB virtual serial port (aka. native USB
port), if the Arduino has one:
// - it does not autoreset (except for the magic baud rate
of 1200).
// - it is more reliable because of USB handshaking.
//
// Leonardo and similar have an USB virtual serial port:
'Serial'.
// Due and Zero have an USB virtual serial port:
'SerialUSB'.
//
// On the Due and Zero, 'Serial' can be used too,
provided you disable autoreset.
// To use 'Serial': #define SERIAL Serial

#ifdef SERIAL_PORT_USBVIRTUAL
#define SERIAL SERIAL_PORT_USBVIRTUAL
#else
#define SERIAL Serial
#endif

// Configure the baud rate:

#define BAUDRATE 19200


// #define BAUDRATE 115200
// #define BAUDRATE 1000000

#define HWVER 2
#define SWMAJ 1
#define SWMIN 18
// STK Definitions
#define STK_OK 0x10
#define STK_FAILED 0x11
#define STK_UNKNOWN 0x12
#define STK_INSYNC 0x14
#define STK_NOSYNC 0x15
#define CRC_EOP 0x20 //ok it is a space...

void pulse(int pin, int times);

#ifdef USE_HARDWARE_SPI
#include "SPI.h"
#else

#define SPI_MODE0 0x00

class SPISettings {
public:
// clock is in Hz
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t
dataMode) : clock(clock){
(void) bitOrder;
(void) dataMode;
};

private:
uint32_t clock;

friend class BitBangedSPI;


};

class BitBangedSPI {
public:
void begin() {
digitalWrite(PIN_SCK, LOW);
digitalWrite(PIN_MOSI, LOW);
pinMode(PIN_SCK, OUTPUT);
pinMode(PIN_MOSI, OUTPUT);
pinMode(PIN_MISO, INPUT);
}

void beginTransaction(SPISettings settings) {


pulseWidth = (500000 + settings.clock - 1) /
settings.clock;
if (pulseWidth == 0)
pulseWidth = 1;
}

void end() {}

uint8_t transfer (uint8_t b) {


for (unsigned int i = 0; i < 8; ++i) {
digitalWrite(PIN_MOSI, (b & 0x80) ? HIGH : LOW);
digitalWrite(PIN_SCK, HIGH);
delayMicroseconds(pulseWidth);
b = (b << 1) | digitalRead(PIN_MISO);
digitalWrite(PIN_SCK, LOW); // slow pulse
delayMicroseconds(pulseWidth);
}
return b;
}

private:
unsigned long pulseWidth; // in microseconds
};

static BitBangedSPI SPI;

#endif

void setup() {
SERIAL.begin(BAUDRATE);

pinMode(LED_PMODE, OUTPUT);
pulse(LED_PMODE, 2);
pinMode(LED_ERR, OUTPUT);
pulse(LED_ERR, 2);
pinMode(LED_HB, OUTPUT);
pulse(LED_HB, 2);
}

int error = 0;
int pmode = 0;
// address for reading and writing, set by 'U' command
unsigned int here;
uint8_t buff[256]; // global block storage

#define beget16(addr) (*addr * 256 + *(addr+1) )


typedef struct param {
uint8_t devicecode;
uint8_t revision;
uint8_t progtype;
uint8_t parmode;
uint8_t polling;
uint8_t selftimed;
uint8_t lockbytes;
uint8_t fusebytes;
uint8_t flashpoll;
uint16_t eeprompoll;
uint16_t pagesize;
uint16_t eepromsize;
uint32_t flashsize;
}
parameter;

parameter param;
// this provides a heartbeat on pin 9, so you can tell the
software is running.
uint8_t hbval = 128;
int8_t hbdelta = 8;
void heartbeat() {
static unsigned long last_time = 0;
unsigned long now = millis();
if ((now - last_time) < 40)
return;
last_time = now;
if (hbval > 192) hbdelta = -hbdelta;
if (hbval < 32) hbdelta = -hbdelta;
hbval += hbdelta;
analogWrite(LED_HB, hbval);
}

static bool rst_active_high;

void reset_target(bool reset) {


digitalWrite(RESET, ((reset && rst_active_high) ||
(!reset && !rst_active_high)) ? HIGH : LOW);
}

void loop(void) {
// is pmode active?
if (pmode) {
digitalWrite(LED_PMODE, HIGH);
} else {
digitalWrite(LED_PMODE, LOW);
}
// is there an error?
if (error) {
digitalWrite(LED_ERR, HIGH);
} else {
digitalWrite(LED_ERR, LOW);
}

// light the heartbeat LED


heartbeat();
if (SERIAL.available()) {
avrisp();
}
}

uint8_t getch() {
while (!SERIAL.available());
return SERIAL.read();
}
void fill(int n) {
for (int x = 0; x < n; x++) {
buff[x] = getch();
}
}
#define PTIME 30
void pulse(int pin, int times) {
do {
digitalWrite(pin, HIGH);
delay(PTIME);
digitalWrite(pin, LOW);
delay(PTIME);
} while (times--);
}

void prog_lamp(int state) {


if (PROG_FLICKER) {
digitalWrite(LED_PMODE, state);
}
}

uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c,


uint8_t d) {
SPI.transfer(a);
SPI.transfer(b);
SPI.transfer(c);
return SPI.transfer(d);
}

void empty_reply() {
if (CRC_EOP == getch()) {
SERIAL.print((char)STK_INSYNC);
SERIAL.print((char)STK_OK);
} else {
error++;
SERIAL.print((char)STK_NOSYNC);
}
}

void breply(uint8_t b) {
if (CRC_EOP == getch()) {
SERIAL.print((char)STK_INSYNC);
SERIAL.print((char)b);
SERIAL.print((char)STK_OK);
} else {
error++;
SERIAL.print((char)STK_NOSYNC);
}
}

void get_version(uint8_t c) {
switch (c) {
case 0x80:
breply(HWVER);
break;
case 0x81:
breply(SWMAJ);
break;
case 0x82:
breply(SWMIN);
break;
case 0x93:
breply('S'); // serial programmer
break;
default:
breply(0);
}
}

void set_parameters() {
// call this after reading paramter packet into buff[]
param.devicecode = buff[0];
param.revision = buff[1];
param.progtype = buff[2];
param.parmode = buff[3];
param.polling = buff[4];
param.selftimed = buff[5];
param.lockbytes = buff[6];
param.fusebytes = buff[7];
param.flashpoll = buff[8];
// ignore buff[9] (= buff[8])
// following are 16 bits (big endian)
param.eeprompoll = beget16(&buff[10]);
param.pagesize = beget16(&buff[12]);
param.eepromsize = beget16(&buff[14]);
// 32 bits flashsize (big endian)
param.flashsize = buff[16] * 0x01000000
+ buff[17] * 0x00010000
+ buff[18] * 0x00000100
+ buff[19];

// avr devices have active low reset, at89sx are active


high
rst_active_high = (param.devicecode >= 0xe0);
}

void start_pmode() {

// Reset target before driving PIN_SCK or PIN_MOSI

// SPI.begin() will configure SS as output,


// so SPI master mode is selected.
// We have defined RESET as pin 10,
// which for many arduino's is not the SS pin.
// So we have to configure RESET as output here,
// (reset_target() first sets the correct level)
reset_target(true);
pinMode(RESET, OUTPUT);
SPI.begin();
SPI.beginTransaction(SPISettings(SPI_CLOCK,
MSBFIRST, SPI_MODE0));
// See avr datasheets, chapter "SERIAL_PRG
Programming Algorithm":

// Pulse RESET after PIN_SCK is low:


digitalWrite(PIN_SCK, LOW);
delay(20); // discharge PIN_SCK, value arbitrally chosen
reset_target(false);
// Pulse must be minimum 2 target CPU clock cycles
// so 100 usec is ok for CPU speeds above 20KHz
delayMicroseconds(100);
reset_target(true);

// Send the enable programming command:


delay(50); // datasheet: must be > 20 msec
spi_transaction(0xAC, 0x53, 0x00, 0x00);
pmode = 1;
}

void end_pmode() {
SPI.end();
// We're about to take the target out of reset
// so configure SPI pins as input
pinMode(PIN_MOSI, INPUT);
pinMode(PIN_SCK, INPUT);
reset_target(false);
pinMode(RESET, INPUT);
pmode = 0;
}

void universal() {
uint8_t ch;

fill(4);
ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
breply(ch);
}

void flash(uint8_t hilo, unsigned int addr, uint8_t data) {


spi_transaction(0x40 + 8 * hilo,
addr >> 8 & 0xFF,
addr & 0xFF,
data);
}
void commit(unsigned int addr) {
if (PROG_FLICKER) {
prog_lamp(LOW);
}
spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF,
0);
if (PROG_FLICKER) {
delay(PTIME);
prog_lamp(HIGH);
}
}

unsigned int current_page() {


if (param.pagesize == 32) {
return here & 0xFFFFFFF0;
}
if (param.pagesize == 64) {
return here & 0xFFFFFFE0;
}
if (param.pagesize == 128) {
return here & 0xFFFFFFC0;
}
if (param.pagesize == 256) {
return here & 0xFFFFFF80;
}
return here;
}

void write_flash(int length) {


fill(length);
if (CRC_EOP == getch()) {
SERIAL.print((char) STK_INSYNC);
SERIAL.print((char) write_flash_pages(length));
} else {
error++;
SERIAL.print((char) STK_NOSYNC);
}
}

uint8_t write_flash_pages(int length) {


int x = 0;
unsigned int page = current_page();
while (x < length) {
if (page != current_page()) {
commit(page);
page = current_page();
}
flash(LOW, here, buff[x++]);
flash(HIGH, here, buff[x++]);
here++;
}

commit(page);

return STK_OK;
}

#define EECHUNK (32)


uint8_t write_eeprom(unsigned int length) {
// here is a word address, get the byte address
unsigned int start = here * 2;
unsigned int remaining = length;
if (length > param.eepromsize) {
error++;
return STK_FAILED;
}
while (remaining > EECHUNK) {
write_eeprom_chunk(start, EECHUNK);
start += EECHUNK;
remaining -= EECHUNK;
}
write_eeprom_chunk(start, remaining);
return STK_OK;
}
// write (length) bytes, (start) is a byte address
uint8_t write_eeprom_chunk(unsigned int start,
unsigned int length) {
// this writes byte-by-byte,
// page writing may be faster (4 bytes at a time)
fill(length);
prog_lamp(LOW);
for (unsigned int x = 0; x < length; x++) {
unsigned int addr = start + x;
spi_transaction(0xC0, (addr >> 8) & 0xFF, addr & 0xFF,
buff[x]);
delay(45);
}
prog_lamp(HIGH);
return STK_OK;
}
void program_page() {
char result = (char) STK_FAILED;
unsigned int length = 256 * getch();
length += getch();
char memtype = getch();
// flash memory @here, (length) bytes
if (memtype == 'F') {
write_flash(length);
return;
}
if (memtype == 'E') {
result = (char)write_eeprom(length);
if (CRC_EOP == getch()) {
SERIAL.print((char) STK_INSYNC);
SERIAL.print(result);
} else {
error++;
SERIAL.print((char) STK_NOSYNC);
}
return;
}
SERIAL.print((char)STK_FAILED);
return;
}

uint8_t flash_read(uint8_t hilo, unsigned int addr) {


return spi_transaction(0x20 + hilo * 8,
(addr >> 8) & 0xFF,
addr & 0xFF,
0);
}

char flash_read_page(int length) {


for (int x = 0; x < length; x += 2) {
uint8_t low = flash_read(LOW, here);
SERIAL.print((char) low);
uint8_t high = flash_read(HIGH, here);
SERIAL.print((char) high);
here++;
}
return STK_OK;
}

char eeprom_read_page(int length) {


// here again we have a word address
int start = here * 2;
for (int x = 0; x < length; x++) {
int addr = start + x;
uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF,
addr & 0xFF, 0xFF);
SERIAL.print((char) ee);
}
return STK_OK;
}

void read_page() {
char result = (char)STK_FAILED;
int length = 256 * getch();
length += getch();
char memtype = getch();
if (CRC_EOP != getch()) {
error++;
SERIAL.print((char) STK_NOSYNC);
return;
}
SERIAL.print((char) STK_INSYNC);
if (memtype == 'F') result = flash_read_page(length);
if (memtype == 'E') result = eeprom_read_page(length);
SERIAL.print(result);
}

void read_signature() {
if (CRC_EOP != getch()) {
error++;
SERIAL.print((char) STK_NOSYNC);
return;
}
SERIAL.print((char) STK_INSYNC);
uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
SERIAL.print((char) high);
uint8_t middle = spi_transaction(0x30, 0x00, 0x01,
0x00);
SERIAL.print((char) middle);
uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
SERIAL.print((char) low);
SERIAL.print((char) STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////

////////////////////////////////////
////////////////////////////////////
void avrisp() {
uint8_t ch = getch();
switch (ch) {
case '0': // signon
error = 0;
empty_reply();
break;
case '1':
if (getch() == CRC_EOP) {
SERIAL.print((char) STK_INSYNC);
SERIAL.print("AVR ISP");
SERIAL.print((char) STK_OK);
}
else {
error++;
SERIAL.print((char) STK_NOSYNC);
}
break;
case 'A':
get_version(getch());
break;
case 'B':
fill(20);
set_parameters();
empty_reply();
break;
case 'E': // extended parameters - ignore for now
fill(5);
empty_reply();
break;
case 'P':
if (!pmode)
start_pmode();
empty_reply();
break;
case 'U': // set address (word)
here = getch();
here += 256 * getch();
empty_reply();
break;
case 0x60: //STK_PROG_FLASH
getch(); // low addr
getch(); // high addr
empty_reply();
break;
case 0x61: //STK_PROG_DATA
getch(); // data
empty_reply();
break;

case 0x64: //STK_PROG_PAGE


program_page();
break;

case 0x74: //STK_READ_PAGE 't'


read_page();
break;

case 'V': //0x56


universal();
break;
case 'Q': //0x51
error = 0;
end_pmode();
empty_reply();
break;
case 0x75: //STK_READ_SIGN 'u'
read_signature();
break;

// expecting a command, not CRC_EOP


// this is how we can get back in sync
case CRC_EOP:
error++;
SERIAL.print((char) STK_NOSYNC);
break;

// anything else we will return STK_UNKNOWN


default:
error++;
if (CRC_EOP == getch())
SERIAL.print((char)STK_UNKNOWN);
else
SERIAL.print((char)STK_NOSYNC);
}
}
24) Arduino Sun Tracking Solar System
COMPONENTS AND SUPPLIES

Arduino UNO & Genuino


UNO
× 1

Analog Devices LDR Sensor


× 1

Solderless Breadboard Full × 1


Size
solar panel
× 1

SG90 Micro-servo motor


× 2

Jumper wires (generic)


× 1

Resistor 1k ohm
× 4
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT


It seems you can'twalk down the street these days
without coming across a solar panel. You canfind them
for mobile charging in rural areas, as well as simple little
sidewalkpath lights. Solar is easy to use, readily
available, and inexpensive.
Every panel you seein your day to day life is in a fixed
position. While this approach isextremely simple and
meets the needs of most small applications, it
isn'tproducing as much energy as it could be.
Our tracker isa dual axis tracker , meaningit tracks in
both X and Y. To put it into even more simple terms, it
goes left, right, up, and down. This means once you have
your tracker set up you willnever need to change or
adjust anything, since anywhere the sun moves
yourtracker will follow.
SCHEMATICS
CODE

#include<Servo.h> // library for servo motor

Servo s; // define Vertival servo


Servo sh; // define horizontal servo
int start1 = 90; // initially starting from 90 degree
int start2 = 90;
int L1 = A0; //for read data from LDR1
int L2 = A1; //for read data from LDR2
int L3 = A2; //for read data from LDR3
int L4 = A3; //for read data from LDR4
int a = 15;

void setup()
{
s.attach(9); //connect vertical servo to pin 9 of arduino
sh.attach(10); //connect horizontal servo to pin 10 of arduino
pinMode(L1, INPUT); //define LDR as input
pinMode(L2, INPUT);
pinMode(L3, INPUT);
pinMode(L4, INPUT);
s.write(start1); //it will start servo from 90 when we reset system
sh.write(start2);
delay(2000);
}
void loop()
{
int LDR1 = analogRead(L1); //read value from LDR
int LDR2 = analogRead(L2);
int LDR3 = analogRead(L3);
int LDR4 = analogRead(L4);
int plus14 =(LDR1+LDR4); //average of two corner LDR
int plus23 =(LDR2+LDR3);
int plus12 =(LDR1+LDR2);
int plus34 =(LDR3+LDR4);
int diff1= abs(plus14 - plus23); // difference to take proper value
int diff2= abs(plus23 - plus14);
int diff3= abs(plus12 - plus34);
int diff4= abs(plus34 - plus12);

if((diff1 <= a) || (diff2 <= a))


{
//difference is less then 15 so do nothing
}
else
{
if(plus14 > plus23) //move vertical servo in lessthen 90 degree
{
start2= --start2;
}
if(plus14 < plus23)
{
start2 = ++start2; //move vertical servo in greaterthen 90 degree
}
}
if(plus12 > plus34 )
{
start1= --start1; // move horizontal servo in lessthen 90 degree
}
if(plus12 < plus34)
{
start1= ++start1; //move horizontal servo in greaterthen 90 degree
}
s.write(start1);
sh.write(start2);
delay(100);
}
25) Arduino Max 30102 Heart Rate Monitor on LCD
COMPONENTS AND SUPPLIES

Arduino Nano R3
× 1

MAX 30102 Heart rate monitor


× 1

Adafruit RGB Backlight LCD - × 1


16x2
Rotary potentiometer (generic)
× 1
NECESSARY TOOLS AND MACHINES
Soldering iron (generic)
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT


This is a simple heart rate monitor made with a
MAX30102 sensor module. I wrote a simple code
based on Arduino libraries and values are shown on a
16x2 LCD screen. The first row displays averge beats
per minute, and the second row shows the value of the
reflected infrared beam. This value should be constant
to make readings more accurate.Our tracker isa dual
axis tracker, meaningit tracks in both X and Y. To put it
into even more simple terms, it goes left, right, up, and
down. This means once you have your tracker set up you
willnever need to change or adjust anything, since
anywhere the sun moves yourtracker will follow.
SCHEMATICS
CODE

/*
Optical Heart Rate Detection (PBA Algorithm) using the MAX30105
Breakout

This is a demo to show the reading of heart rate or beats per minute (BPM)
using
a Penpheral Beat Amplitude (PBA) algorithm.

It is best to attach the sensor to your finger using a rubber band or other
tightening
device. Humans are generally bad at applying constant pressure to a thing.
When you
press your finger against the sensor it varies enough to cause the blood in
your
finger to flow differently which causes the sensor readings to go wonky.

Hardware Connections (Breakoutboard to Arduino):


-5V = 5V (3.3V is allowed)
-GND = GND
-SDA = A4 (or SDA)
-SCL = A5 (or SCL)
-INT = Not connected
The MAX30105 Breakout can handle 5V or 3.3V I2C logic. We recommend
powering the board with 5V
but it will also run at 3.3V.
*/

#include <Wire.h>
#include "MAX30105.h"
#include <LiquidCrystal.h>

#include "heartRate.h"

MAX30105 particleSensor;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.


byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred

float beatsPerMinute;
int beatAvg;

void setup()
{
Serial.begin(9600);

lcd.begin(16, 2);
Serial.println("Initializing...");

// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port,
400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to
indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
}

void loop()
{
long irValue = particleSensor.getIR();

if (checkForBeat(irValue) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();

beatsPerMinute = 60 / (delta / 1000.0);

if (beatsPerMinute < 255 && beatsPerMinute > 20)


{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable

//Take average of readings


beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}

Serial.print("IR=");
Serial.print(irValue);
Serial.print(", BPM=");
Serial.print(beatsPerMinute);
Serial.print(", Avg BPM=");
Serial.print(beatAvg);

if (irValue < 50000)


Serial.print(" No finger?");

Serial.println();

lcd.setCursor(0,0);
lcd.print("BPM: ");
lcd.print(beatAvg);

lcd.setCursor(0,1);
lcd.print(" IR: ");
lcd.print(irValue);
}

26) Rainfall Measured Using Arduino


COMPONENTS AND SUPPLIES

water sensor
× 1

Arduino UNO & Genuino


UNO
× 1
ABOUT THIS PROJECT
SCHEMATICS
CODE

#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup () {
// initialize serial communication at 9600 bits per second:
Serial.begin (9600);}
void loop() {
// read the input on analog pin 0:
int value = analogRead(A0);
lcd.setCursor(0, 7);
if (value > 500) {
Serial.println("Very heavy Rain");
lcd.print("Very heavy rain");}
else if ((value > 300) && (value <= 500)) {
Serial.println("AVERAGE Rain");
lcd.print("Average Rain");
lcd.print(" "); }
else{
Serial.println("Dry Weather");
lcd.print("Dry Wather");
lcd.print(" ");}
delay(100);}

27) Arduino Touchless Mouse


COMPONENTS AND SUPPLIES
Bitcraze Flow breakout
× 1

Arduino Leonardo
× 1

ABOUT THIS PROJECT


This project implements a touchless mouse.
The Bitcraze flow breakout contains an optical flow
sensor that is able to sense how things are moving in
front of it and a ranging sensor to sense the distance to
the nearest object. The flow sensor is essentially an
optical mouse sensor fitted with a lens focused to
track objects far away.
The touchless mouse can detect that a hand is
approaching and detect how it is moving, the
movements are translated into mouse movements by
an Arduino.
By using an Arduino Leonardo (or any other USB
device-compatible Arduino) this project is seen as a
regular mouse so it works out of the box on any
computer.
Hardware setup
The flow deck is connected to two busses of the
Arduino:
The PMW3901 optical tracking sensor is
connected to the SPI bus
The VL53 ranging sensor is connected to the i2C
bus
We also need to power the flow deck, this is done by
connecting it to the 5V and GND pin of the Arduino.
Note that on Arduino Leonardo, the SPI bus is only
accessible on the ICSP pin header.
Required library
The two sensors require libraries to work. Using
the Arduino IDE Library manager we load the two
libraries:
VL53L0x for the ranging sensor
Bitcraze_pmw3901 for the optical flow sensor

When an object is detected by the ranging sensor, at a


distance between 80mm and 200mm, the movement
measured by the flow sensor is sent as mouse
movement. When the detected object is below 50mm
we press the mouse button. The reason to keep 50mm
to 80mm without motion detection and click is to
make sure that the mouse is clicking without any
movement: without this gap the mouse was always
moving a bit when the hand goes down to click.
SCHEMATICS
CODE

#include "Bitcraze_PMW3901.h"
#include <Wire.h>
#include <VL53L0X.h>
#include <Mouse.h>

VL53L0X rangeSensor;

// Using digital pin 10 for chip select


Bitcraze_PMW3901 flow(10);

void setup() {
Serial.begin(9600);
// Initialize flow sensor
if (!flow.begin()) {
Serial.println("Initialization of the flow sensor failed");
while(1) { }
}
// Initialize range sensor
Wire.begin();
rangeSensor.init();
rangeSensor.setTimeout(500);
// Initialize Mouse
Mouse.begin();
}

int16_t deltaX,deltaY;

void loop() {
// Get motion count since last call
flow.readMotionCount(&deltaX, &deltaY);
// Get single range measurement
float range = rangeSensor.readRangeSingleMillimeters();

// Send motion as mouse movement when the hand is between 80 and


200mm
if (range < 200 && range > 80) {
Mouse.move(deltaX, -deltaY, 0);
}

// Press the left mouse button when the hand is bellow 50mm
if (range < 50) {
Mouse.press();
} else {
Mouse.release();
}
}
28) Arduino Ankle Air Guitar Pedal
COMPONENTS AND SUPPLIES

Arduino Nano R3
any arduino is okay, im thinking on using
tinyduino × 1

mpc41010
× 1
digital potenciometer
SparkFun Triple Axis Accelerometer Breakout × 1
- ADXL335
any analogoutput accelerometer is okay
stereo audio jack 6,5 mm female adapter
× 1

stereo audio jack 6,5 mm cable


× 1

RGB Diffused Common Cathode


just for fun, no needed
× 1
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT


We need to weld the correct things, so follow along.
The current interest in dubstep was growing, and I was
ready to spend 40€ on one expression pedal for
my boss synthesizer when I remembered I was an
electronics nerd.
Then science occurred.
At first, I thought about drilling a shoe and gluing the
electronics inside, but I did not have a pair of shoes to
spare. So, I ended up purchasing a hair band and
stitching thread.
First steps with the MPC digital potentiometers
family:
We have a lot of types to choose from, but I picked
this one - the MPC41010.
MPC41010: single potentiometer, 10k ohm
MPC41050: single potentiometer, 50k ohm
MPC41100: single potentiometer, 100k ohm
MCP42010: two independent potentiometers,
10k ohm
MCP42050: two independent potentiometers,
50k ohm
MCP42100: two independent potentiometers,
100k ohm
More things about them here. Important things that
you need to know for hacking this device:
You can do similar things with other digital
potentiometers. (like the COM-10613, more
info)
The resistance is 0 to 10k ohms divided in 255
steps with each step of 39 ohms. (MATH!)
Serial communication: just use #include
<SPI.h>.

What I learned with the prototype:


When the device is reset, the human needs to set
the flat and the top values for adjusting the range
of movement.
It would be nice to implement a function that
chooses between the axis which had the wider
range of variation. This would be useful so that
you don't have to mind the position of the
accelerometer; you could put it in upside-down, on
the bass top, on your wrist, etc.
Maybe I need to implement a logarithmic
behaviour for the resistance values.
I need to take care of the 0 level because it
is highly instable.
Building the stereo jack 6,5 mm cable
Keep in mind I am poor. So for 4€, I bought the
components (couple of male jack endings and 1 meter of
cable).
We need to weld the correct things, so follow the scheme
and use some hot-shrink tube to do a fine job.
SCHEMATICS
CODE

#include <SPI.h>
#define debug //comment this line if you´re not gonna use the serial data
with the arduino ide

#define CS 10 //chipselect

#define accelerometerX A0//analogpins for the accelerometer


#define accelerometerY A1
#define accelerometerZ A2

#define RED 6 //rgb pins


#define GREEN 3
#define BLUE 5

//MCP41010 chip´s connection


// 39ohms per step of the
//CS 10 U vcc
//SCK 13 serial clock PBO--UPRESISTOR
//SI 11 serial imput PWO INRESISTOR
//gnd PAO--BOTTOMRESISTOR

int datarray[18]={0,0,0,0,0,0,1023,1023,1023,0,0,0,0,0,0};
int smoothingarray[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int rgb[3];
int i=0,chipvalue=0;
int ResistorValue=0;
void setup() {
//
//pinMode (GREEN, OUTPUT);//GREEN RGB (PWM)
//pinMode (BLUE, OUTPUT);//BLUE
//pinMode (RED, OUTPUT);//RED
//digitalWrite(GREEN, HIGH);//setting the led off at the begining
//digitalWrite (BLUE, HIGH);//
//digitalWrite (RED, HIGH);//

pinMode (CS, OUTPUT);//chipselect for the MCP41010 chip


pinMode (13, OUTPUT);//things are happening led
pinMode (accelerometerX, INPUT);//acelerometer´s inputs
pinMode (accelerometerY, INPUT);//
pinMode (accelerometerZ, INPUT);//
SPI.begin();
MCP41010Write(0);//init value horizontal foot

#ifdef debug
Serial.begin(9600);
#endif
}

void loop() {
datarray[0]=analogRead(accelerometerX);
datarray[1]=analogRead(accelerometerY);
datarray[2]=analogRead(accelerometerZ);

comparemaxmin(datarray);

detectRange(datarray);

ResistorValue=map(datarray[datarray[15]],datarray[datarray[15]+6]+20,dat
array[datarray[15]+3]-10,0,255);//+20 to the min and -10 to the max for
preventing unreachable edges

chipvalue =constrain(ResistorValue,0,255);

MCP41010Write(smoothing(chipvalue));

// //map(value, fromLow, fromHigh, toLow, toHigh)


// for(i=0;i<=2;i++){
// rgb[i]=map(datarray[i],datarray[i+6],datarray[i+3],0,255);
// }
////analogWrite(GREEN, rgb[0]);//EL LED DA PROBLEMAS DE
LECTURA ruido/////////////////////7
////analogWrite (BLUE, rgb[1]);//
////analogWrite (RED, rgb[2]);//

#ifdef debug
Serial.print("//RawReadings: ");
Serial.print(datarray[0]);
Serial.print(" ");
Serial.print(datarray[1]);
Serial.print(" ");
Serial.print(datarray[2]);

Serial.print(" /max ");


Serial.print(datarray[3]);
Serial.print(" ");
Serial.print(datarray[4]);
Serial.print(" ");
Serial.print(datarray[5]);

Serial.print(" /min ");


Serial.print(datarray[6]);
Serial.print(" ");
Serial.print(datarray[7]);
Serial.print(" ");
Serial.print(datarray[8]);

Serial.print(" //GAP :");


Serial.print(datarray[9]);
Serial.print(" ");
Serial.print(datarray[10]);
Serial.print(" ");
Serial.print(datarray[11]);

// Serial.print("/?? ");
// Serial.print(datarray[12]);
// Serial.print(" ");
// Serial.print(datarray[13]);
// Serial.print(" ");
// Serial.print(datarray[14]);

Serial.print(" //axis choose ");


Serial.print(datarray[15]);

Serial.print(" //chip value ");


Serial.print(chipvalue);

Serial.println();
#endif
delay(100);//delay for stability
}

void comparemaxmin(int datarray[])


{
for(i=0;i<=2;i++)
datarray[i+3]=max(datarray[i],datarray[i+3]);

for(i=0;i<=2;i++)
datarray[i+6]=min(datarray[i],datarray[i+6]);

void detectRange(int datarray[18])


{
for(i=0;i<=2;i++)
{
datarray[i+9]=abs(abs(datarray[i+3])-abs(datarray[i+6]));
}
if(datarray[9]>=datarray[10]&&datarray[9]>=datarray[11])//choosing the
axis with the wider range
datarray[15]=0;
if(datarray[10]>=datarray[9]&&datarray[10]>=datarray[11])
datarray[15]=1;
if(datarray[11]>=datarray[9]&&datarray[11]>=datarray[10])
datarray[15]=2;
}

void MCP41010Write(byte value) //speaking protocol with the mcp chip


{
// Note that the integer value passed to this subroutine
// is cast to a byte

digitalWrite(CS,LOW);
SPI.transfer(B00010001); // This tells the chip to set the pot
SPI.transfer(value); // This tells it the pot position
digitalWrite(CS,HIGH);
}

int smoothing(int data){


int result,j;

for(j=0;j<=14;j++){
smoothingarray[j] = smoothingarray[j+1];
}
smoothingarray[14]= data;

result=
(smoothingarray[0]+smoothingarray[1]+smoothingarray[2]+smoothingarray
[3]+smoothingarray[4])/5;
constrain(result,0,255);
return result;
}

29) Arduino Word Clock


COMPONENTS AND SUPPLIES

Arduino UNO & Genuino


UNO
× 1
any microcontroller will do

Real Time Clock (RTC) × 1


Texas Instruments 74hc595
× 1
shift register
STMicroelectronics uln2803a
× 1
darlington array
led strip
× 1

ic holders 16pin x3 and 18pin


x3 × 1

12v power supply


× 1
NECESSARY TOOLS AND MACHINES
mount board

acrylic board
APPS AND ONLINE SERVICES
Arduino IDE

rtc library

ABOUT THIS PROJECT


Introduction
All you need is an arduino and a RTC. I have removed
the switches and other hardware. Since DS1307 is
pretty stable, it does not require frequent time
changes! It will also keep the time even if there is a
power failure, thanks to its internal 3v battery. This
battery will last for years.
So even if you are going on a vacation, just turn off
the clock and the time will be running accurate when
you turn it back on!
I have made the code as simple as possible! It just
reads time from the RTC and updates the shift
registers.
Step 1: Collecting the Parts –
ELECTRONICS COMPONENTS USED
Main parts
Arduino or just atmega328p as i have used
(standalone) x1
RTC (Real Time Clock) DS1307 x1
Shift registers 74hc595 x3
ULN2803a Darlington Transistor Arrays as LED
drivers x3
LED strip I have used white...approx 2m
16 pin IC socket x3
18 pin IC socket x3
12v power source may be battery or wall adapter
Miscellaneous
Proto board / general PCB board
Connecting wires
Male header pins
Jumper wires- female-female
basic soldering
FRAME AND STENCIL
Mount board / thick cardboard
Glue, Tape
Scissors, Paper cutter
Acrylic Board (translucent white) / Plexi glass
Snickering of Words
Step 2: Making the Connections....
Follow the simple circuit diagram shown above.
I have used a standalone arduino which I can program
with FTDI cables, but any arduino board can be used
!!For this project even though we control 22
individual LED arrays, we just use 5 I/O pins from the
arduino ie.- 3 for shift Registors and 2 for RTC
module.
Using shift resistors is a great way to increase the i/o
pins.
Important thing about ULN2803a Drivers -
This IC is a darlington pair.
Hence connect all the cathodes [positive terminals] of
the LEDs to the source and the anodes
[negative/ground] to the respective output terminals of
the driver!
Step 3: Building the Frame
Here I have used mount board for the construction...
It is easy to cut, bend and handle the mount board. It
is also has less strength.
Any material like wood, plastic, metal etc. can be
used.
Cut a piece of mount board the size of the front
Board with words.
Make a rough sketch of the words and their
alignment on the board.
Cut strips of mount board of size may be 1.5 cm..
This is to make compartments, the size of the
words. this will prevent the light from one word
to diffuse and illuminate the surrounding words.
Place the strips horizontally after each line of
words and vertically in between the words; make
small boxes for each of the word.
Finally make a box that will sneakily fit the
electronics, the LED board, anti-diffusion boxes
and the outermost board with words stickered on
to it.
Step 4: Connecting the LEDs
I'm using the LED strip in this project. It is easy to
operate. It can be cut for desired length, no need of
soldering each and every led to make an array. LED
Strips also come with a peel-off sticker at the back.
Just cut the required length of the strip depending on
the size of the word and stick it on the LED board (
mount board). Remember that most of the led strips
have connectors at an interval of 3 LEDs. So you have
to cut at the indicated points only. Therefore even the
smallest word will have 3 LEDs.
You can even use the standard LEDs, solder them for
desired number of LEDs. Remember to use the
resistor for each array that you make. the value of the
resistor depends on the specifications of the LEDs
used. You can check here for further info, LED
calc or this one.
Connect all the Positive terminals of the LED strip
together. This is the common Vcc for the leds.
You can see that i have connected it using thin copper
wire. Then Connect wires for all the individual ground
terminals for each word and bring it back to connect it
to the driver.
Step 5: The Codes
The originalcode itself is well commented and easily
understandable.
The #define section allots the pins on the shift register
for individual words. They will be updated each time
when the time changes.
The void WriteLEDs function updates the shift regesters
through the data pin.
The void self-test function blinks all the LED words in a sequence so that you
know everythingis working correctly. i.e. for
troubleshooting.
The void displaytime function will check the time with the RTC
chip and see which words to be illuminated accordingly.
The rest can be easily made out by the code itself.
GitHub

Step 6: Finishing It Off.


Place all the controller boards; arduino and circuit
which contains shift registers, RTC chip and LED
drivers.
Connect the LED arrays of each word to the
respective pin of the driver.
Place the LED board inside the casing and fix it
in place...
The main outer stencil is made by sticking the
words onto any acrylic or plastic.
Make a hole at the back for fixing the clock for
using a nail.

SCHEMATICS
CODE

/*

RTClib information---
SDA pin -----> A4 / D18
SCL pin -----> A5 / D19
*/

#include <string.h>
#include <Wire.h>
#include"RTClib.h"

// Display output pin assignments


#define MINUTES Display1=Display1 | B00000001
#define MTEN Display1=Display1 | B00000010
#define HALF Display1=Display1 | B00000100
#define PAST Display1=Display1 | B00001000
#define THREE Display1=Display1 | B00010000
#define ITIS Display1=Display1 | B00100000
#define TWENTY Display1=Display1 | B01000000
#define TO Display1=Display1 | B10000000

#define TWO Display2=Display2 | B00000001


#define SIX Display2=Display2 | B00000010
#define TWELVE Display2=Display2 | B00000100
#define HFIVE Display2=Display2 | B00001000
#define SEVEN Display2=Display2 | B00010000
#define OCLOCK Display2=Display2 | B00100000
#define ONE Display2=Display2 | B01000000
#define QUARTER Display2=Display2 | B10000000

#define EIGHT Display3=Display3 | B00000001


#define MFIVE Display3=Display3 | B00000010
#define ARDUINO Display3=Display3 | B00000100
#define ELEVEN Display3=Display3 | B00001000
#define HTEN Display3=Display3 | B00010000
#define NINE Display3=Display3 | B00100000
#define FOUR Display3=Display3 | B01000000
#define RBK Display3=Display3 | B10000000

int hour=0, minute=0, second=0;


static unsigned long msTick =0; // the number of Millisecond Ticks since
we last
// incremented the second counter
int selftestmode; // 1 = in self test - flash display
char Display1=0, Display2=0, Display3=0;

// hardware constants
int LEDClockPin=8; // Arduino Pin#8 - Shift register 74HC595 Pin 11
clock
int LEDDataPin=9; // Arduino Pin#9 - Shift register 74HC595 pin 14 Data
int LEDLatchPin=10; // Arduino Pin#10 - Shift register 74HC595 pin 12
Latch

// RTC DEFINE-
RTC_DS1307 RTC ;

void setup()
{
// initialise the hardware
// initialize the appropriate pins as outputs:
pinMode(LEDClockPin, OUTPUT);
pinMode(LEDDataPin, OUTPUT);
pinMode(LEDLatchPin, OUTPUT);

Serial.begin(9600); // setup the serial port to 9600 baud


Wire.begin();
RTC.begin();

// test whether the DS1307 is there


Serial.print("Verifying DS1307 ");

if ( RTC.isrunning()) {
Serial.println("RTC is running.....");
DateTime now = RTC.now();

Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}

DateTime now = RTC.now();


msTick=millis(); // Initialise the msTick counter

selftest(); // validate the hardware for the user

selftestmode=0;

if ( RTC.isrunning() ) {
// Get the current time and date from the RTC chip

second=now.second();
minute=now.minute();
hour=now.hour();
}

displaytime(); // display the current time


}

void WriteLEDs(){
// Now we write the actual values to the hardware
shiftOut(LEDDataPin, LEDClockPin, MSBFIRST, Display3);
shiftOut(LEDDataPin, LEDClockPin, MSBFIRST, Display2);
shiftOut(LEDDataPin, LEDClockPin, MSBFIRST, Display1);
digitalWrite(LEDLatchPin,HIGH);
//delay(2);
digitalWrite(LEDLatchPin,LOW);

void ledsoff(void) {
Display1=0;
Display2=0;
Display3=0;

void selftest(void){
// start by clearing the display to a known state
ledsoff();
ITIS;
WriteLEDs();
delay(500);
ledsoff();
MTEN;
WriteLEDs();
delay(500);
ledsoff();
HALF;
WriteLEDs();
delay(500);
ledsoff();
TWENTY;
WriteLEDs();
delay(500);
ledsoff();
QUARTER;
WriteLEDs();
delay(500);
ledsoff();
MFIVE;
WriteLEDs();
delay(500);
ledsoff();
MINUTES;
WriteLEDs();
delay(500);
ledsoff();
PAST;
WriteLEDs();
delay(500);
ledsoff();
TO;
WriteLEDs();
delay(500);
ledsoff();
ONE;
WriteLEDs();
delay(500);
ledsoff();
TWO;
WriteLEDs();
delay(500);
ledsoff();
THREE;
WriteLEDs();
delay(500);
ledsoff();
FOUR;
WriteLEDs();
delay(500);
ledsoff();
HFIVE;
WriteLEDs();
delay(500);
ledsoff();
SIX;
WriteLEDs();
delay(500);
ledsoff();
SEVEN;
WriteLEDs();
delay(500);
ledsoff();
EIGHT;
WriteLEDs();
delay(500);
ledsoff();
NINE;
WriteLEDs();
delay(500);
ledsoff();
HTEN;
WriteLEDs();
delay(500);
ledsoff();
ELEVEN;
WriteLEDs();
delay(500);
ledsoff();
TWELVE;
WriteLEDs();
delay(500);
ledsoff();
OCLOCK;
WriteLEDs();
delay(500);
ledsoff();
RBK;
WriteLEDs();
delay(500);
ledsoff();
ARDUINO;
WriteLEDs();
delay(500);
ledsoff();

for(int i=0; i<5; i++)


{
Display1=255;
Display2=255;
Display3=255;
WriteLEDs();
delay(500);
ledsoff();
WriteLEDs();
delay(500);
}

void displaytime(void){

// start by clearing the display to a known state


ledsoff();

// Now, turn on the "It is" leds


ITIS;
Serial.print("It is ");

// now we display the appropriate minute counter


if ((minute>4) && (minute<10)) {
MFIVE;
MINUTES;
Serial.print("Five Minutes ");
}
if ((minute>9) && (minute<15)) {
MTEN;
MINUTES;
Serial.print("Ten Minutes ");
}
if ((minute>14) && (minute<20)) {
QUARTER;
Serial.print("Quarter ");
}
if ((minute>19) && (minute<25)) {
TWENTY;
MINUTES;
Serial.print("Twenty Minutes ");
}
if ((minute>24) && (minute<30)) {
TWENTY;
MFIVE;
MINUTES;
Serial.print("Twenty Five Minutes ");
}
if ((minute>29) && (minute<35)) {
HALF;
Serial.print("Half ");
}
if ((minute>34) && (minute<40)) {
TWENTY;
MFIVE;
MINUTES;
Serial.print("Twenty Five Minutes ");
}
if ((minute>39) && (minute<45)) {
TWENTY;
MINUTES;
Serial.print("Twenty Minutes ");
}
if ((minute>44) && (minute<50)) {
QUARTER;
Serial.print("Quarter ");
}
if ((minute>49) && (minute<55)) {
MTEN;
MINUTES;
Serial.print("Ten Minutes ");
}
if (minute>54) {
MFIVE;
MINUTES;
Serial.print("Five Minutes ");
}

if ((minute <5))
{
switch (hour) {
case 1:
case 13:
ONE;
Serial.print("One ");
break;
case 2:
case 14:
TWO;
Serial.print("Two ");
break;
case 3:
case 15:
THREE;
Serial.print("Three ");
break;
case 4:
case 16:
FOUR;
Serial.print("Four ");
break;
case 5:
case 17:
HFIVE;
Serial.print("Five ");
break;
case 6:
case 18:
SIX;
Serial.print("Six ");
break;
case 7:
case 19:
SEVEN;
Serial.print("Seven ");
break;
case 8:
case 20:
EIGHT;
Serial.print("Eight ");
break;
case 9:
case 21:
NINE;
Serial.print("Nine ");
break;
case 10:
case 22:
HTEN;
Serial.print("Ten ");
break;
case 11:
case 23:
ELEVEN;
Serial.print("Eleven ");
break;
case 0:
case 12:
TWELVE;
Serial.print("Twelve ");
break;
}
OCLOCK;
Serial.println("O'Clock");
}
else
if ((minute < 35) && (minute >4))
{
PAST;
Serial.print("Past ");
switch (hour) {
case 1:
case 13:
ONE;
Serial.println("One ");
break;
case 2:
case 14:
TWO;
Serial.println("Two ");
break;
case 3:
case 15:
THREE;
Serial.println("Three ");
break;
case 4:
case 16:
FOUR;
Serial.println("Four ");
break;
case 5:
case 17:
HFIVE;
Serial.println("Five ");
break;
case 6:
case 18:
SIX;
Serial.println("Six ");
break;
case 7:
case 19:
SEVEN;
Serial.println("Seven ");
break;
case 8:
case 20:
EIGHT;
Serial.println("Eight ");
break;
case 9:
case 21:
NINE;
Serial.println("Nine ");
break;
case 10:
case 22:
HTEN;
Serial.println("Ten ");
break;
case 11:
case 23:
ELEVEN;
Serial.println("Eleven ");
break;
case 0:
case 12:
TWELVE;
Serial.println("Twelve ");
break;
}
}
else
{
// if we are greater than 34 minutes past the hour then display
// the next hour, as we will be displaying a 'to' sign
TO;
Serial.print("To ");
switch (hour) {
case 1:
case 13:
TWO;
Serial.println("Two ");
break;
case 14:
case 2:
THREE;
Serial.println("Three ");
break;
case 15:
case 3:
FOUR;
Serial.println("Four ");
break;
case 4:
case 16:
HFIVE;
Serial.println("Five ");
break;
case 5:
case 17:
SIX;
Serial.println("Six ");
break;
case 6:
case 18:
SEVEN;
Serial.println("Seven ");
break;
case 7:
case 19:
EIGHT;
Serial.println("Eight ");
break;
case 8:
case 20:
NINE;
Serial.println("Nine ");
break;
case 9:
case 21:
HTEN;
Serial.println("Ten ");
break;
case 10:
case 22:
ELEVEN;
Serial.println("Eleven ");
break;
case 11:
case 23:
TWELVE;
Serial.println("Twelve ");
break;
case 0:
case 12:
ONE;
Serial.println("One ");
break;
}
}

void loop()
{
DateTime now = RTC.now();

second=now.second();
minute=now.minute();
hour=now.hour();

//Serial.println("Loop Started");

// Flash the onboard Pin13 Led every 5 sec so we know something is


hapening!
if ( millis() - msTick >5000) {
msTick=millis();

digitalWrite(13,HIGH);
delay(50);
digitalWrite(13,LOW);
delay(50);
digitalWrite(13,HIGH);
delay(50);
digitalWrite(13,LOW);

Serial.print(second);
Serial.print("..");
}

if (second==59) // Update the display every 1 minute...


{
displaytime();
WriteLEDs();
}

30) Arduino Traffic Advisor


COMPONENTS AND SUPPLIES
Arduino Nano R3
× 1

3 mm LED: Yellow
× 8

3 mm LED: Green
× 1

Pushbutton Switch, Momentary


4 pin, small generaic push × 6
button

Resistor 220 ohm


× 6

Hook Up Wire Kit, 22 AWG


× 1
ControlEverything.com Relay × 1
Shield for Particle Photon I²C 8-
Channel SPDT 10-Amp

Adafruit NeoPixel Digital RGB


LED Strip 144 LED, 1m White
× 1
NECESSARY TOOLS AND MACHINES
Soldering iron (generic)

Solder Wire, Lead Free

Wire Stripper & Cutter, 18-10 AWG /


0.75-4mm² Capacity Wires

ABOUT THIS PROJECT


I wanted to see how hard it would be to make this.
this is a traffic advisor controller.
it controls 8 light segments and has a small led readout
to show you what pattern is currently being used.
a power light to show that power is on.
6 buttons that do various actions
button 1: left arrow
button 2: center out
button 3: right arrow
button 4: warning patterns
button 5: switch warning pattern
button 6: turn off lights/ save warning pattern
there are the 3 directional patterns and 10 warning
patterns.
any mode can be activated at any time with no delay.
warning patterns are:
1:even / odd fast flash
2: half and half
3: half and half with fast flash
4: 2 by 2
5: 2 by 2 parallel
6: out flash
7: 3 out center
8: outboard
9:inboard
10: even / odd slow
SCHEMATICS
CODE

#include <EEPROM.h>
int warning_button = A5;
int left_button = 2;
int center_button = 4;
int right_button = 3;
int off_button = A0;
int pattern_button = A2;
int statuslight = 13;
int LEDright[] = {5, 6, 7, 8, 9, 10, 11, 12};
int LEDleft[] = {12, 11, 10, 9, 8, 7, 6, 5};
int centerleft[] = {9, 10, 11, 12};
int centerright[] = {8, 7, 6, 5};
int light = 0;
int counter = 1;
int pattern_count = 0;
int warning_count = EEPROM.read(0);
long lasttimer = 0;
static long timer = 200;
static long timer2 = 300;
static long switch_timer = 4000;
#define LEFTside 0x0
#define RIGHTside 0x1
byte whichLED = LEFTside;
byte LEFT_state = LOW;
byte RIGHT_state = LOW;
unsigned long switchDelay = 1000;
unsigned long switchDelay2 = 500;
unsigned long strobeDelay = 75;
unsigned long strobeWait = strobeDelay;
unsigned long waitUntilSwitch = switchDelay;
unsigned long sequenceStartTime;
//----------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
for (int i = 0; i < 8; i++) {
pinMode(LEDright[i], OUTPUT);
}
pinMode(statuslight, OUTPUT);
pinMode(warning_button, INPUT_PULLUP);
pinMode(left_button, INPUT_PULLUP);
pinMode(center_button, INPUT_PULLUP);
pinMode(right_button, INPUT_PULLUP);
pinMode(off_button, INPUT_PULLUP);
pinMode(pattern_button, INPUT_PULLUP);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);
}
//------------------------------------------------------------------------
void loop() {
digitalWrite(13, HIGH);
delayMicroseconds(10); // Approximately 10% duty cycle @ 1KHz
digitalWrite(13, LOW);
delayMicroseconds(1000 - 10);
if (digitalRead(pattern_button) == HIGH)
{
delay(500);
warning_count++;
if (warning_count > 10) {
warning_count = 1;
}
}
if (digitalRead(warning_button) == HIGH)
{
delay(50);
pattern_count = 1;
}
if (digitalRead(left_button) == HIGH)
{
delay(50);
pattern_count = 2;
}
if (digitalRead(center_button) == HIGH)
{
delay(50);
pattern_count = 3;
}
if (digitalRead(right_button) == HIGH)
{
delay(50);
pattern_count = 4;
}
if (digitalRead(off_button) == HIGH)
{
delay(50);
pattern_count = 0;
EEPROM.update(0,warning_count);
}
switch (pattern_count) {
case 0:
pattern_off();
break;
case 1:
traffic_left();
break;
case 2:
traffic_center();
break;
case 3:
traffic_right();
break;
case 4:
traffic_warning();
break;
}
}
void pattern_off() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
}
void traffic_left() {
unsigned long currenttimer = millis();
if (currenttimer - lasttimer >= timer) {
lasttimer = currenttimer;
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(LEDleft[light], LOW);
light = light + counter;
if (light > 7) {
light = 0;
counter = 1;
}
digitalWrite(LEDleft[light], HIGH);
}
}
void traffic_center() {
unsigned long currenttimer = millis();
if (currenttimer - lasttimer >= timer2) {
lasttimer = currenttimer;
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(centerright[light], LOW);
digitalWrite(centerleft[light], LOW);
light = light + counter;
if (light > 3) {
light = 0;
counter = 1;
}
digitalWrite(centerright[light], HIGH);
digitalWrite(centerleft[light], HIGH);
}
}
void traffic_right() {
unsigned long currenttimer = millis();
if (currenttimer - lasttimer >= timer) {
lasttimer = currenttimer;
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(LEDright[light], LOW);
light = light + counter;
if (light > 7) {
light = 0;
counter = 1;
}
digitalWrite(LEDright[light], HIGH);
}
}
void traffic_warning() {
switch (warning_count) {
case 1:
even_odd_flash();
break;
case 2:
half_half();
break;
case 3:
half_half_flash();
break;
case 4:
two_by_two();
break;
case 5:
two_by_two_parallel();
break;
case 6:
out_flash();
break;
case 7:
one_center();
break;
case 8:
outboard();
break;
case 9:
inboard();
break;
case 10:
even_odd();
break;
}
}
void even_odd_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, RIGHT_state);
digitalWrite(10, LEFT_state);
digitalWrite(9, RIGHT_state);
digitalWrite(8, LEFT_state);
digitalWrite(7, RIGHT_state);
digitalWrite(6, LEFT_state);
digitalWrite(5, RIGHT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void half_half_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, LEFT_state);
digitalWrite(10, LEFT_state);
digitalWrite(9, LEFT_state);
digitalWrite(8, RIGHT_state);
digitalWrite(7, RIGHT_state);
digitalWrite(6, RIGHT_state);
digitalWrite(5, RIGHT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay2;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void half_half() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 250)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 500)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void out_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 150)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else if (time < 300)
{
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, LOW);
}
else sequenceStartTime = millis();
}
void two_by_two() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 150)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else if (time < 300)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else sequenceStartTime = millis();
}
void two_by_two_parallel() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 150)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 300)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void one_center() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 500)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 1000)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void outboard() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 200)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 400)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void inboard() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 200)
{
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
}
else if (time < 400)
{
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
}
else sequenceStartTime = millis();
}
void even_odd() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 300)
{
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, LOW);
}
else if (time < 600)
{
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
31) Arduino Word Clock on 8X8 RGB LED Matrix

COMPONENTS AND SUPPLIES


Arduino Nano R3 × 1

Full-color RGB 8x8


LED+Colorful Magic Matrix
Driver shield Colorduino KIT × 1
DIY

Maxim Integrated DS1307 64 x


8, Serial, I²C Real-Time Clock
× 1

SparkFun Pushbutton switch


12mm
× 2

Photo resistor
× 1

Rotary potentiometer (generic)


× 1
NECESSARY TOOLS AND MACHINES
Soldering iron (generic)
APPS AND ONLINE SERVICES
Arduino IDE

ABOUT THIS PROJECT


Full-color RGB 8x8 LED+Colorful Magic Matrix
Driver shield Colorduino KIT DIY" which is also
known as Funduino, consists of the 8x8 RGB LED
matrix and driver shield (control board with atmega
chip and LED drivers).
This is probably the best project that can be done with
this module. There are many projects on the Internet
that are just pattern generators and nothing more.
Mark Wilson made an intuitive word clock, and even
wrote his own library "chromaduino" which you can
find at GitHub:
https://github.com/funnypolynomial/Chromaduino
It drives the LEDs and receives display information
from a master over I2C.
Now I will try to explain step by step the construction
of this device. First, you have to program the control
board. For this purpose we take Arduino Uno, from
which we extract the Atmega chip, and connect with
the control board in the following way:
GND-GND, 5V-VCC, RX(D0)-RXD, TX(D1)-TXD
and RESET-DTR (Arduino-Control board)
In Arduino IDE we choose the appropriate serial port
and Duemilanove board and upload chromaduino.ino
library. This will program the ATmega on the
Funduino/Colorduino board. The matrix is placed on
the control board in a way that pin 1 on the matrix
goes to Blue pin 1 on the board.
Next, we need to program the Arduino Nano (master)
board, and on it, through the I2C protocol connect
Colorduino and DS3231 Real-time clock module as
described in the scheme below. There are also two
buttons ("Adj" and "Set") connected to the analog
inputs A2 and A3 that are used to set the clock:
- Pressing Adj cycles through color modes: RGB, reds,
greens, blues, white(ish) and random. Unless the
current time is on the hour, in which case it toggles
showing NONE/EVEN
- Pressing and holding Set sets the display dimming,
first the ambient level to "DIM AT" then the
brightness to "DIM TO"
- Pressing Set and Adj cycles through display off and
alternate faces
- Holding Set at power on runs the LED matrix demo
- Holding Adj at power on runs the clock in demo
mode
- Holding Set and Adj at power on resets the clock
configuration
The clock contains two Clock faces. The first face
("Half Ten") shows the time as MINUTES TO HOUR
or MINUTES OF HOUR, for example, FIFTEEN TO
TEN (at 9:45) or FIFTEEN OF TEN (at 10:15). The
second face ("Ten Thirty") simply shows the time as
HOUR MINUTES, for example, TEN FIFTEEN (at
10:15).
I made the letter plates at a local graphic design
company where I printed faces on a transparent plastic
plate, and for better visibility, I put a sheet of white
paper between a plastic grid and a letter plate. I have
printed the plastic grid on my 3D printer.
SCHEMATICS
CODE

#include "arduino.h"
#include <avr/pgmspace.h>
#include <Wire.h>
#include <EEPROM.h>
#include "PINS.h"
#include "RTC.h"
#include "LDR.h"
#include "LEDS.h"
#include "BTN.h"
#include "CFG.h"
#include "CLK.h"

/*
A "word clock" showing the time on one of two 8x8
character grids:
TWENONTY or THRTWONE
FIFVTEEN TWELEVEN
HALFMTOF ENEIGHTI
FOURFIVE SIXSEVEN
SIXSEVEN FOURFIVE
EIGHTHRI THIRTWEN
TWELEVEN MFIFORTY
ONETWOEE EFIVTEEN

Driving an 8x8 RGB LED matrix.

Mark Wilson
15 Dec 2016 - Initial version
*/

//#define _DEBUG

void setup()
{
#ifdef _DEBUG
Serial.begin(38400);
Serial.println("wordclok");
#endif

pins.setup();
digitalWrite(PINS::STD_LED, HIGH);
rtc.setup();
#ifndef _DEBUG
randomSeed(rtc.getSeed());
#endif
ldr.setup();
leds.setup();
cfg.setup();
clk.setup();
digitalWrite(PINS::STD_LED, LOW);
}

void loop()
{
clk.loop();
}
32) Arduino Indoor NeoPixel Thermometer
COMPONENTS AND SUPPLIES
Arduino UNO & Genuino
UNO
× 1

NeoPixel
× 1

LCD readout
× 1

TMP36 sensor
× 1

Resistor 1k ohm × 1
470 ohm resistor
× 1

Rotary potentiometer (generic)


× 1

Simple momentary switch


× 1

F to M jumper wires
× 1
for the LCD
M to M Jumpers
× 1
for everything else
Breadboard (generic)
× 1

ABOUT THIS PROJECT


This is a quick, intermediate Arduino project that
takes a temperature reading from a TMP36 , reads it
onto an LCD screen and gives an "Analog" readout on
a Neopixel stick that changes color and number of
lights lit every 10 degrees Fahrenheit. It's easily
customizable as NeoPixels can be coded in many ways
so the NeoPixel stick can change size and colors every
which way a maker would want it to.
Step 1: Gather Components
For this build you will need an Arduino (any one will
do, I used Uno), NeoPixels (can be found here) an
LCD screen (I used this one) a TMP36 sensor (or
comparable, I used this inexpensive one from Adafruit
) a 1k ohm resistor, a 470 ohm resistor, a
potentiometer, a simple momentary switch, F to M
jumper wires (for the LCD) and M to M Jumpers (for
everything else) and a breadboard.

Step 2: Construct Circuit


Fritzing View of Circuit
From the fritzing diagram the circuit looks a little
confusing but it's actually relatively simple. What is
important to take note is you're going to want the
TMP36 on a separate circuit from the rest of the
project because some noise that's caused by the Pixels
messes up the voltage readout from the TMP36 and in
turn the temperature reading. When it comes to the
Pixels a bit a soldering is going to have to happen.
You're going to want to use 4 plain, everyday headers,
and solder them directly onto the NeoPixel stick. It's
absolutely imperative that you get the pin out correct
on this otherwise you'll have to de and resolder the
headers and trust me, the copper pads on the
NeoPixels do not like being resoldered and while
NeoPixels are not the most expensive component in
the world, several sticks that are rendered unusable
because the copper pads have been taken off add up
very quickly. To solder you will want a good iron and
a solder with a thin gauge. A pair of "third hands" are
especially useful in this project as the headers can be
tricky to solder onto the stick straight if the stick is
lying on the table.
How I set up the pixels and header in the Third hand
NeoPixel PinOut
I included a photo with the proper pin order, the side
with "DIN" goes to the breadboard/Arduino and the
side "DOUT" goes to other pixels or just the air. You
can use any number of NeoPixels, the one at the
Studio has 4 sticks for an especially prominent read
out that would be ideal if you were to enclose it in a
laser cut acrylic display (possibly stay tuned). On the
other hand, and as seen in one of the photos, I have a
smaller one using only one stick that works just fine at
home that you could then also turn into a wall
mounted display with a very quick enclosure. That's
one of the things with NeoPixels that make them
great, it doesn't take much code to make them fit
almost any size or form factor.
The pin out from the Arduino goes as follows:
A0 to Vout on TMP36
3.3V to TMP36 PWR Rail
AREF to TMP36 PWR Rail //AREF takes a
reference voltage and gives a more accurate
reading than just taking //straight from the
source, you'll see why this is important on the
next page
GND to TMP36 GND rail
5V to Primary PWR rail
other GND to Primary GND rail
13 to pin 4 on LCD
12 to momentary switch //while not necessary I
included a momentary switch that, when pressed
will switch //between Celsius and Fahrenheit
readout on the LCD
11 to pin 6 on LCD
6 to 470 ohm resistor leading to DIN on
NeoPixels //resistor prevents surges and damage
to the pixel stick
5 to pin 11 on LCD
4 to pin 12 on LCD
3 to pin 13 on LCD
2 to pin 14 on LCD
Other pinouts on LCD Screen
LCD pin 1 to one leg of potentiometer leading to
Primary GND rail
LCD pin 2 to one leg of potentiometer leading to
Primary PWR rail
LCD pin 3 to middle leg or "wiper" of
potentiometer //this controls contrast on the
screen
LCD pin 5 to primary GND rail
LCD pin 15 to primary PWR rail
LCD pin 16 to primary GND rail
The rest of the circuit is pretty self explanatory and
clear on the Fritzing Diagram, just remember to keep
the TMP36 and Primary circuits separate.
SCHEMATICS
CODE

#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>

// Create a variable that will store the temperature value


int TMPin = 0;
const int button = 12;
int lastColor = -1;

#define aref_voltage 3.3


#define PIN 6

/*
Param 1 == number of pixels
Param 2 == Arduino pin attached to din
Param 3 == pixel type flags, add together as needed
NE0_KHZ800 800 KHZ bitstream (avg neopix)
NE0_GRB wired for GRB bitstream
*/
Adafruit_NeoPixel strip = Adafruit_NeoPixel(32, PIN,
NEO_GRB + NEO_KHZ800); //call Neopixels, 32
pixels in all, on pin 6, RGB system and 800 KHZ
LiquidCrystal lcd(13, 11, 5, 4, 3, 2); //call LCD display
void setup()
{
lcd.begin(16,2); //initialize LCD screen 16 by 2
strip.begin(); //begin neo pixel strip
strip.show(); //initialize strip
Serial.begin(9600);// serial monitor access
pinMode(button, INPUT); //button for celsius
analogReference(EXTERNAL); //analog reference for
use with TMP36
}

void loop()
{
double temperature;
double temp;
double tempF;

temp = tempMeasure(temperature); //call tempMeasure


function
tempF = (temp * 9.0/5.0 + 32); //take reading from
tempMeasure and convert to faharenheit

while(digitalRead(button) == false) //button is depressed


readout is in Celsius
{
Serial.println(temp); //prints in serial monitor
lcd.print(temp); //prints on LCD screen
lcd.setCursor(0,1); //sets cursor
delay(2000); //2 seconds between readings
lcd.clear(); //clear LCD after 2 seconds
}

pixelCaseF(tempF); //call pixelCase function that


controls lights
Serial.println(tempF); //print in serial
lcd.print(tempF); //print temp in F on LCD
lcd.setCursor(0,1); //set cursor
delay(2000); //take reading every 2 seconds
lcd.clear(); //clear LCD

}//end loop

double tempMeasure(double temperature)


{
// -----------------
// Read temperature
// -----------------

int reading = analogRead(TMPin); //voltage reading


double voltage = reading * aref_voltage; //take initial
reading and multiply by 3.3 ref voltage for arduino

voltage /= 1024.0; //divide reading by 1024 to map

temperature = (voltage - 0.5) * 100; //converts 10mv per


degree with 500 mV offset to (voltage - 500mV) * 100)

return temperature; //return temperature to top level


method

}//end tempMeasure

void pixelCaseF(double tempF)


/*
This method controls the neo-pixel for the "analog"
readout on the thermometer. With every temperature
group, the number of pixels lit changes along with the
color
*/

{
int i;
strip.setBrightness(64);
strip.show();
if (tempF >= 90.05)//if above 90 degrees, strip is red and
entire strip is lit
{
strip.clear();
for(int i=0;i <= 32;i++)
{
strip.setPixelColor(i, strip.Color(255,0,0));
}
}
else if (tempF < 90.2 && tempF >= 80.05) //if 90 >
tempF >= 80 orange and strip is partially lit up to 29th
pixel
{
strip.clear();
for(int i=0;i <= 28;i++)
{
strip.setPixelColor(i, strip.Color(255,128,0));
}
}
else if (tempF < 80.02 && tempF >= 70.5)// if 80 >
tempF >= 70 yellow-green and strip is lit up to 25th
pixel
{
strip.clear();
for(int i = 0; i <= 24; i++)
{
strip.setPixelColor(i,strip.Color(204,255,0));
}
}
else if (tempF < 70 && tempF >= 60.5)// if 70 > tempF
>= 60 green and strip is lit up to 21st pixel
{
strip.clear();
for(int i = 0; i<= 20; i++)
{
strip.setPixelColor(i,strip.Color(0,255,0));
}
}
else if (tempF < 60.02 && tempF >= 50.5) //if 60 >
tempF >= 50 blue and strip is lit up to 17th pixel
{
strip.clear();
for(int i = 0; i <= 16; i++)
{
strip.setPixelColor(i,strip.Color(0,0,255));
}
}
else if (tempF < 50.02 && tempF >= 40.5) //if 50 >
tempF >= 40 aqua and strip is lit to 13th pixel
{
strip.clear();
for(int i = 0; i <= 12; i++)
{
strip.setPixelColor(i, strip.Color(0,255,255));
}
}
else if (tempF < 40.02 && tempF >= 32.5) //if 40 >
tempF >= 32 fuschia and strip is lit to 9th pixel
{
strip.clear();
for(int i = 0; i <= 8; i++)
{
strip.setPixelColor(i, strip.Color(153, 51,255));
}
}
else if (tempF < 32.5) //temp < freezing white and strip
is lit to 5th pixel
{
strip.clear();
for(i = 0;i <= 4; i++)
{
strip.setPixelColor(i, strip.Color(255,255,255));
}//end for
}

strip.show(); //update color change

}//end pixelCase
33) Arduino LCD Video Game
COMPONENTS AND SUPPLIES

Breadboard (generic)
× 1

Jumper wires (generic)


× 1
Arduino UNO & Genuino UNO × 1

USB-A to B Cable
× 1

Rotary potentiometer (generic)


× 1

Analog joystick (Generic)


× 1

Buzzer
× 1

Adafruit Standard LCD - 16x2


White on Blue
× 1
APPS AND ONLINE SERVICES

Arduino IDE

ABOUT THIS PROJECT

This is a project that is based on a video game that I


found on the internet. This project has many features
such as a buzzer for beeping when your character
collides or jumps over obstacles. Also, to give it a
video game feeling, it has a joystick (must have a
button) because you simply press down on the
joystick's button to jump. This video game is about
you guessed it! (A man running and jumping over
obstacles and avoiding them.) The object of this game
is about getting as many points as possible (one point
for every second you are on the course and avoiding
the obstacles).

SCHEMATICS
CODE

#include <LiquidCrystal.h>

#define PIN_BUTTON 2
#define PIN_AUTOPLAY 1
#define PIN_BUZZER 8
#define PIN_READWRITE 10
#define PIN_CONTRAST 12

#define SPRITE_RUN1 1
#define SPRITE_RUN2 2
#define SPRITE_JUMP 3
#define SPRITE_JUMP_UPPER '.' // Use the '.' character for the head
#define SPRITE_JUMP_LOWER 4
#define SPRITE_TERRAIN_EMPTY ' ' // User the ' ' character
#define SPRITE_TERRAIN_SOLID 5
#define SPRITE_TERRAIN_SOLID_RIGHT 6
#define SPRITE_TERRAIN_SOLID_LEFT 7

#define HERO_HORIZONTAL_POSITION 1 // Horizontal position of


hero on screen

#define TERRAIN_WIDTH 16
#define TERRAIN_EMPTY 0
#define TERRAIN_LOWER_BLOCK 1
#define TERRAIN_UPPER_BLOCK 2

#define HERO_POSITION_OFF 0 // Hero is invisible


#define HERO_POSITION_RUN_LOWER_1 1 // Hero is running on lower
row (pose 1)
#define HERO_POSITION_RUN_LOWER_2 2 // (pose
2)
#define HERO_POSITION_JUMP_1 3 // Starting a jump
#define HERO_POSITION_JUMP_2 4 // Half-way up
#define HERO_POSITION_JUMP_3 5 // Jump is on upper row
#define HERO_POSITION_JUMP_4 6 // Jump is on upper row
#define HERO_POSITION_JUMP_5 7 // Jump is on upper row
#define HERO_POSITION_JUMP_6 8 // Jump is on upper row
#define HERO_POSITION_JUMP_7 9 // Half-way down
#define HERO_POSITION_JUMP_8 10 // About to land

#define HERO_POSITION_RUN_UPPER_1 11 // Hero is running on upper


row (pose 1)
#define HERO_POSITION_RUN_UPPER_2 12 // (pose
2)

LiquidCrystal lcd(11, 9, 6, 5, 4, 3);


static char terrainUpper[TERRAIN_WIDTH + 1];
static char terrainLower[TERRAIN_WIDTH + 1];
static bool buttonPushed = false;

void initializeGraphics(){
static byte graphics[] = {
// Run position 1
B01100,
B01100,
B00000,
B01110,
B11100,
B01100,
B11010,
B10011,
// Run position 2
B01100,
B01100,
B00000,
B01100,
B01100,
B01100,
B01100,
B01110,
// Jump
B01100,
B01100,
B00000,
B11110,
B01101,
B11111,
B10000,
B00000,
// Jump lower
B11110,
B01101,
B11111,
B10000,
B00000,
B00000,
B00000,
B00000,
// Ground
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
// Ground right
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
// Ground left
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
};
int i;
// Skip using character 0, this allows lcd.print() to be used to
// quickly draw multiple characters
for (i = 0; i < 7; ++i) {
lcd.createChar(i + 1, &graphics[i * 8]);
}
for (i = 0; i < TERRAIN_WIDTH; ++i) {
terrainUpper[i] = SPRITE_TERRAIN_EMPTY;
terrainLower[i] = SPRITE_TERRAIN_EMPTY;
}
}

// Slide the terrain to the left in half-character increments


//
void advanceTerrain(char* terrain, byte newTerrain){
for (int i = 0; i < TERRAIN_WIDTH; ++i) {
char current = terrain[i];
char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1];
switch (current){
case SPRITE_TERRAIN_EMPTY:
terrain[i] = (next == SPRITE_TERRAIN_SOLID) ?
SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY;
break;
case SPRITE_TERRAIN_SOLID:
terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ?
SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID;
break;
case SPRITE_TERRAIN_SOLID_RIGHT:
terrain[i] = SPRITE_TERRAIN_SOLID;
break;
case SPRITE_TERRAIN_SOLID_LEFT:
terrain[i] = SPRITE_TERRAIN_EMPTY;
break;
}
}
}

bool drawHero(byte position, char* terrainUpper, char* terrainLower,


unsigned int score) {
bool collide = false;
char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION];
char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION];
byte upper, lower;
switch (position) {
case HERO_POSITION_OFF:
upper = lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_LOWER_1:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_RUN1;
break;
case HERO_POSITION_RUN_LOWER_2:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_RUN2;
break;
case HERO_POSITION_JUMP_1:
case HERO_POSITION_JUMP_8:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_JUMP;
break;
case HERO_POSITION_JUMP_2:
case HERO_POSITION_JUMP_7:
upper = SPRITE_JUMP_UPPER;
lower = SPRITE_JUMP_LOWER;
break;
case HERO_POSITION_JUMP_3:
case HERO_POSITION_JUMP_4:
case HERO_POSITION_JUMP_5:
case HERO_POSITION_JUMP_6:
upper = SPRITE_JUMP;
lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_UPPER_1:
upper = SPRITE_RUN1;
lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_UPPER_2:
upper = SPRITE_RUN2;
lower = SPRITE_TERRAIN_EMPTY;
break;
}
if (upper != ' ') {
terrainUpper[HERO_HORIZONTAL_POSITION] = upper;
collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true;
}
if (lower != ' ') {
terrainLower[HERO_HORIZONTAL_POSITION] = lower;
collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true;
}

byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score
> 9) ? 2 : 1;

// Draw the scene


terrainUpper[TERRAIN_WIDTH] = '\0';
terrainLower[TERRAIN_WIDTH] = '\0';
char temp = terrainUpper[16-digits];
terrainUpper[16-digits] = '\0';
lcd.setCursor(0,0);
lcd.print(terrainUpper);
terrainUpper[16-digits] = temp;
lcd.setCursor(0,1);
lcd.print(terrainLower);

lcd.setCursor(16 - digits,0);
lcd.print(score);

terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave;
terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave;
return collide;
}

// Handle the button push as an interrupt


void buttonPush() {
buttonPushed = true;
}

void setup(){
pinMode(PIN_READWRITE, OUTPUT);
digitalWrite(PIN_READWRITE, LOW);
pinMode(PIN_CONTRAST, OUTPUT);
digitalWrite(PIN_CONTRAST, LOW);
pinMode(PIN_BUTTON, INPUT);
digitalWrite(PIN_BUTTON, HIGH);
pinMode(PIN_AUTOPLAY, OUTPUT);
digitalWrite(PIN_AUTOPLAY, HIGH);
pinMode(PIN_BUZZER,OUTPUT);//initialize the buzzer pin as an output
digitalWrite(PIN_BUZZER, LOW);

// Digital pin 2 maps to interrupt 0


attachInterrupt(0/*PIN_BUTTON