0% found this document useful (0 votes)
694 views3,101 pages

Elif Avcu - 220 Fun Projects With Arduino (2020)

Uploaded by

Alex Orange
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)
694 views3,101 pages

Elif Avcu - 220 Fun Projects With Arduino (2020)

Uploaded by

Alex Orange
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

220 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, × 2
17cm)

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, does
× 1
not have to be UNO

DC-DC 1.5-3V to 300-400V 380V


High Voltage Boost Step-up
Voltage Inverter Module
Ideal final voltage is 400V, but × 1
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 will
× 1
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 this × 1
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


touchscreen × 1
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,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,0x7
0x0,0x0,0xf,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xfe,0x0,0x0,0x0,0x0,0x0,0x7f
0x0,0x3,0xf8,0x0,0x0,0x7,0xf0,0x0,0x0,0x0,0x7,0xf0,0x0,0x0,0x3,0xf8,0x0,0x0,0x0,0xf,0xe0
0x0,0x3f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x3e,0x0,0x0,0x0,0x0,0x1f,0x0,0x0,0x0,0x7e,0x0
0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,0x0,0xf8,0x0
0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x1,0xf0,0x0
0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x1,0xf0,0x0,0x0,0x0,0x0,0x3,0xe0,0x0,0x0,0xf0,0x0
0x0,0xf8,0x0,0x0,0x0,0x0,0x7,0xc0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xf,0x80,0x0,0x0,0x7c,
0x0,0x3f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x1f,0x80,0x0,0x0,0x0,0x7e,0x0,0x0,0x0,0xf,0xc0
0x0,0x3,0xf8,0x0,0x0,0x7,0xf0,0x0,0x0,0x0,0x1,0xfe,0x0,0x0,0x1f,0xe0,0x0,0x0,0x0,0x0,0xff
0x0,0x0,0xf,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,0x3,0xff,0xff,0xf0,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
};
const unsigned char x_bitmap[]PROGMEM={
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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
0x1,0xff,0xff,0xe0,0x1,0xff,0xff,0xc0,0x0,0x1,0xff,0xff,0xf0,0x3,0xff,0xff,0xc0,0x0,0x0,0xff
0x0,0x3f,0xff,0xfc,0xf,0xff,0xfe,0x0,0x0,0x0,0x3f,0xff,0xfe,0x1f,0xff,0xfe,0x0,0x0,0x0,0x1f
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0x0,0x7,0xff,0xff,0xff,0xff,0xf0,0x0,0x0,0x0,0x3,0xff
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,0x0,0x0,0x1f,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,0x1f
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,0x0,0x0,0x7f,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0xff
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,0x0,0x3,
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0x0,0x1f,0xff,0xff,0x7f,0xff,0xfc,0x0,0x0,0x0,0x1f
0x0,0x7f,0xff,0xf8,0x1f,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xf8,0xf,0xff,0xff,0x80,0x0,0x0,0xff
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,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


12mm
× 1

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 LCD


Display Module
× 1
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
White on Blue
× 1

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 PCBA


× 1

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


Matrix × 1
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','19b10002e8f2537e4f6cd104768a1214','19b10

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 on
the breadboard. You can use FTDI × 1
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 to
× 1
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 Size

× 1
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 -


16x2
× 1
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
- ADXL335
any analogoutput accelerometer is okay × 1
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,datarray[datarray[15
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
constrain(result,0,255);
return result;
}

29) Arduino Word Clock


COMPONENTS AND SUPPLIES

Arduino UNO & Genuino UNO


any microcontroller will do
× 1

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 original code 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
everything is 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 button
× 6

Resistor 220 ohm

× 6

Hook Up Wire Kit, 22 AWG

× 1

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

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 DIY × 1

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*/, buttonPush, FALLING);

initializeGraphics();

lcd.begin(16, 2);
}

void loop(){
static byte heroPos = HERO_POSITION_RUN_LOWER_1;
static byte newTerrainType = TERRAIN_EMPTY;
static byte newTerrainDuration = 1;
static bool playing = false;
static bool blink = false;
static unsigned int distance = 0;
if (!playing) {
drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower,
distance >> 3);
if (blink) {
lcd.setCursor(0,0);
lcd.print("Press Start");
}
delay(250);
blink = !blink;
if (buttonPushed) {

initializeGraphics();
heroPos = HERO_POSITION_RUN_LOWER_1;
playing = true;
buttonPushed = false;
distance = 0;
}
return;
}

// Shift the terrain to the left


advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ?
SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ?
SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);

// Make new terrain to enter on the right


if (--newTerrainDuration == 0) {
if (newTerrainType == TERRAIN_EMPTY) {
newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK :
TERRAIN_LOWER_BLOCK;
newTerrainDuration = 2 + random(10);
} else {
newTerrainType = TERRAIN_EMPTY;
newTerrainDuration = 10 + random(10);
}
}

if (buttonPushed) {
if (heroPos <= HERO_POSITION_RUN_LOWER_2) heroPos =
HERO_POSITION_JUMP_1;
buttonPushed = false;
digitalWrite(PIN_BUZZER,HIGH);
}

if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) {


playing = false; // The hero collided with something. Too bad.
for (int i = 0; i <= 2; i++) {
digitalWrite(PIN_BUZZER, HIGH);
delay(100);
digitalWrite(PIN_BUZZER, LOW);
delay(100);
}
} else {
if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos ==
HERO_POSITION_JUMP_8) {
heroPos = HERO_POSITION_RUN_LOWER_1;
} else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <=
HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] !=
SPRITE_TERRAIN_EMPTY) {
heroPos = HERO_POSITION_RUN_UPPER_1;
} else if (heroPos >= HERO_POSITION_RUN_UPPER_1 &&
terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) {
heroPos = HERO_POSITION_JUMP_5;
} else if (heroPos == HERO_POSITION_RUN_UPPER_2) {
heroPos = HERO_POSITION_RUN_UPPER_1;
} else {
++heroPos;
}
++distance;

digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 2] ==
SPRITE_TERRAIN_EMPTY ? HIGH : LOW);
}
delay(100);
digitalWrite(PIN_BUZZER,LOW);
}
34) Arduino Turn Your RC Car to Bluetooth RV Car
COMPONENTS AND SUPPLIES

SparkFun Arduino Pro Mini 328 -


3.3V/8MHz
× 1

Texas Instruments Dual H-Bridge


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

ABOUT THIS PROJECT

Step 1: Getting the right chassis


Part List
ProMini
L293d module
hc-05
Rc car
Getting the right chassis
To choose chassis is a question about drive mechanism there are many
drive mechanism.
Lets talk about the two most popular mechanism.
Differential Drive What is Differential drive?
The term differential means difference between two entities, in the
context of robotics it is just the speed difference between two
motors.Based on this speed difference, a robot can be moved in any
direction on a 2D layout.
When two motors are connected to wheels in one line,opposite to each
other(Just like a pair of wheels connected to a single shaft) the speed
with which each motor rotates determines the direction of motion.
When both the wheels rotate at the same speed the difference between
the motors is Zero. This makes the robot move forward in a straight
line.The robot can move in reverse direction if the direction of rotation
of both the motors are reversed. This will again be in a straight line if
the speed difference is zero. Now changing the speed of any one motor
will result in movement in a direction away from the straight line. For
example, reducing the speed of the right motor will result in a speed
difference and hence change in direction.The resultant force is such
that the robot turns right. This direction change can be controlled to
required angle by further reducing the speed of the motor.Slower is the
right motor, sharper is the turn to right. This is exactly the same for
Left turn.
As a conclusion, Slower right motor, sharper right turn. Slower left
motor Sharper left turn. Below are some scenarios which explains
working of differential drive mechanism. M1 and M2 are motors which
drive wheels on left and right respectively.
Steer Type Drive
What is Steer type drive ?
The car type drive is the most common in real world but not in robot
world. It is characterized by a pair of driving wheels and a separate pair
of steering wheels The translation and rotation are independent of each
other. But translation and rotation are interlinked hence this system
faces severe path planning problem. Four wheels are more efficient
compared to three or two wheels. The first two of the four wheels can
be used to steer and the next two to drive the robot. Balancing a four
wheeled robot is never an issue. Most everyday cars we use are four
wheeled and the example is enough to prove its existence and
capabilities.
Disadvantages Of Car Type Drive : The turning mechanism mus