The function of this sketch is same as the sketch posted on May. 11, 2014, but using I2C LCD Keypad Shield as the output device.
Sketch
/*
SimpleReceiveI2CLCD
This sketch displays text strings received using VirtualWire
Connect the Receiver data pin to Arduino pin 11
Modified by Befun Hung on Nov. 09, 2014
Use I2C LCD Keypad Shield as the output
*/
#include <VirtualWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// #define BACKLIGHT_PIN 13
LiquidCrystal_I2C lcd(0x20); //Set the LCD I2C address
// LiquidCrystal_I2C lcd(0x38, BACKLIGHT_PIN, POSITIVE);
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
void setup()
{
// pinMode(BACKLIGHT_PIN, OUTPUT);
// digitalWrite(BACKLIGHT_PIN, HIGH);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2); //initialize the lcd
// Print a message to the LCD.
lcd.home(); //go home
lcd.print("Device is ready!");
//
Serial.begin(9600);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
lcd.clear();
Serial.print(counter);
Serial.print(": ");
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 0);
lcd.print(counter);
lcd.print(":");
lcd.setCursor(0,1);
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
lcd.print(char(message[i]));
}
Serial.println();
counter++;
}
}
2014/11/09
2014/10/29
Arduino Sketch for Address Settable RF Wireless Power Supply Socket/Switch
Updated Sketch (Nov. 15,2014)
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// This sketch uses VirtualWire
// Connect the Receiver data pin to Arduino pin 11
// Modified by Befun Hung on Nov. 14, 2014 by combining sketches on May. 11, 2014 (Arduino RF Wireless Message Display)
// and Jul. 30, 2014 (Use DIP Switch To Set Arduino Device Net ID And Node ID for Wireless Communication - Updated Sketch)
// and removing LCD Keypad Shield display function as a new sketch for Arduino addressable RF wireless power supply socket
// Modified by Befun Hung on Nov. 12, 2014 to use
// 4 digital pins(D2-D5) to set node ID1 and
// 4 digital pins(D6-D9) to set node ID2 by using 10K pull-up resistors.
// Totally 8x16x16=2,048 devices can be used for wireless communication
// For practical use 8x10x10=800 devices can be controlled using digital key of 3x4 telephone keypad
// Wire and DIP switch connections from high bit to low bit are A1, A2, A3, D2, D3, D4, D5, D6, D7, D8 and D9
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D13 is used for singal output
// Don't run this sketch on Arduino Pro Mini, it may reboot repeatedly owing to bootloader not supporting watchdog
#include <VirtualWire.h>
// include avr/wdt for watchdog reset
#include <avr/wdt.h>
// include <EEPROM.h> to save switch staus to EEPROM
#include <EEPROM.h>
// keys to turn switch on and off
#define keyOn '*'
#define keyOff '#'
//Create and Define Global Variables
int bits=4, netID, nodeID1, nodeID2;
int dipNet[] = {15, 16, 17}; // DIP Switch Pins for Net ID
int dipNode1[] = {2, 3, 4, 5}; // DIP Switch Pins for Node ID1
int dipNode2[] = {6, 7, 8, 9}; // DIP Switch Pins for Node ID2
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
// digital pin 13 connected with a 1K resistor and a LED
int led = 13;
// Address of EEPROM for saving switch status and variable to store value
int address = 5;
int value;
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
// delay(100);
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode1[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID1 = node1Address(bits);
// delay(100);
Serial.print("Node ID1: ");
Serial.println(nodeID1);
for(i = 0; i<bits; i++){
pinMode(dipNode2[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID2 = node2Address(bits);
// delay(100);
Serial.print("Node ID2: ");
Serial.println(nodeID2);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
//initialize the digital 13 pin as output
pinMode(led, OUTPUT);
// When the receiver is unstable and reboot, reading stored status from EEPROM
value = EEPROM.read(address);
if (value == '1')
{
digitalWrite(led, HIGH);
}
if (value == '0')
{
digitalWrite(led, LOW);
}
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
Serial.print(counter);
Serial.print(": ");
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
}
// if length of received message is less than transmitter sent meaning the receiver is unstable
if (messageLength < 4)
{
software_Reboot();
}
else
{
// netID and nodeID are numbers and message is charactor array, so convention is required
if ((message[0] == (netID + '0')) && (message[1] == (nodeID1 + '0')) && (message[2] == (nodeID2 + '0')))
{
if (message[3] == keyOn)
{
digitalWrite(led, HIGH);
EEPROM.write(address, '1');
}
else
{
if (message[3] == keyOff)
{
digitalWrite(led, LOW);
EEPROM.write(address, '0');
}
}
}
}
Serial.println();
counter++;
}
}
// Software reboot function
void software_Reboot()
{
wdt_enable(WDTO_15MS);
while (1)
{
}
}
//Create Net Address from DIP Switch (3 positions used A1-A3)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D2-D5)
byte node1Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode1[i])); // read the input pin
}
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D6-D9)
byte node2Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode2[i])); // read the input pin
}
return j; //return address
}
Sketch
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// This sketch uses VirtualWire
// Connect the Receiver data pin to Arduino pin 11
// Modified by Befun Hung on Oct. 29, 2014 by combining sketches on May. 11, 2014 (Arduino RF Wireless Message Display)
// and Jul. 30, 2014 (Use DIP Switch To Set Arduino Device Net ID And Node ID for Wireless Communication)
// and removing LCD Keypad Shield display function as a new sketch for Arduino addressable RF wireless power socket
// The sketch uses 3 analog pins(A1-A3) to set net ID and 8 digital pins(D2-D9) to set node ID by using 10K pull-up resistors.
// Totally 8x256=2,048 devices can be used for wireless communication
// When using a 3x4 telephone keypad, 8x10(0-9)=80 devices can be used
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D13 is used for singal output
#include <VirtualWire.h>
// include avr/wdt for watchdog reset
#include <avr/wdt.h>
// include <EEPROM.h> to save switch staus to EEPROM
#include <EEPROM.h>
// keys to turn switch on and off
#define keyOn '1'
#define keyOff '0'
//Create and Define Global Variables
int bits=8;
byte netID, nodeID;
int dipNet[] = {15, 16, 17}; //DIP Switch Pins for Net ID
int dipNode[] = {2, 3, 4, 5, 6, 7, 8, 9}; //DIP Switch Pins for Node ID
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
// digital pin 13 connected with a 1K resistor and a LED
int led = 13;
// Address of EEPROM for saving switch status and variable to store value
int address = 5;
int value;
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode[i], INPUT); // sets the digital pin 2-9 as input
}
nodeID = nodeAddress(bits);
Serial.print("Node ID: ");
Serial.println(nodeID);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
//initialize the digital 13 pin as output
pinMode(led, OUTPUT);
// When the receiver is unstable and reboot, reading stored status from EEPROM
value = EEPROM.read(address);
if (value == '1')
{
digitalWrite(led, HIGH);
}
if (value == '0')
{
digitalWrite(led, LOW);
}
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
Serial.print(counter);
Serial.print(": ");
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
}
// if length of received message is less than transmitter sent meaning the receiver is unstable
if (messageLength < 3)
{
software_Reboot();
}
else
{
// netID and nodeID are numbers and message is charactor array, so convention is required
if ((message[0] == (netID + '0')) && (message[1] == (nodeID + '0')))
{
if (message[2] == keyOn)
{
digitalWrite(led, HIGH);
EEPROM.write(address, '1');
}
else
{
if (message[2] == keyOff)
{
digitalWrite(led, LOW);
EEPROM.write(address, '0');
}
}
}
}
Serial.println();
counter++;
}
}
// Software reboot function
void software_Reboot()
{
wdt_enable(WDTO_15MS);
while (1)
{
}
}
//Create Net Address from DIP Switch (3 positions used)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node Address from DIP Switch (8 positions used D2 - D9)
byte nodeAddress(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode[i])); // read the input pin
}
return j; //return address
}
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// This sketch uses VirtualWire
// Connect the Receiver data pin to Arduino pin 11
// Modified by Befun Hung on Nov. 14, 2014 by combining sketches on May. 11, 2014 (Arduino RF Wireless Message Display)
// and Jul. 30, 2014 (Use DIP Switch To Set Arduino Device Net ID And Node ID for Wireless Communication - Updated Sketch)
// and removing LCD Keypad Shield display function as a new sketch for Arduino addressable RF wireless power supply socket
// Modified by Befun Hung on Nov. 12, 2014 to use
// 4 digital pins(D2-D5) to set node ID1 and
// 4 digital pins(D6-D9) to set node ID2 by using 10K pull-up resistors.
// Totally 8x16x16=2,048 devices can be used for wireless communication
// For practical use 8x10x10=800 devices can be controlled using digital key of 3x4 telephone keypad
// Wire and DIP switch connections from high bit to low bit are A1, A2, A3, D2, D3, D4, D5, D6, D7, D8 and D9
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D13 is used for singal output
// Don't run this sketch on Arduino Pro Mini, it may reboot repeatedly owing to bootloader not supporting watchdog
#include <VirtualWire.h>
// include avr/wdt for watchdog reset
#include <avr/wdt.h>
// include <EEPROM.h> to save switch staus to EEPROM
#include <EEPROM.h>
// keys to turn switch on and off
#define keyOn '*'
#define keyOff '#'
//Create and Define Global Variables
int bits=4, netID, nodeID1, nodeID2;
int dipNet[] = {15, 16, 17}; // DIP Switch Pins for Net ID
int dipNode1[] = {2, 3, 4, 5}; // DIP Switch Pins for Node ID1
int dipNode2[] = {6, 7, 8, 9}; // DIP Switch Pins for Node ID2
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
// digital pin 13 connected with a 1K resistor and a LED
int led = 13;
// Address of EEPROM for saving switch status and variable to store value
int address = 5;
int value;
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
// delay(100);
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode1[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID1 = node1Address(bits);
// delay(100);
Serial.print("Node ID1: ");
Serial.println(nodeID1);
for(i = 0; i<bits; i++){
pinMode(dipNode2[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID2 = node2Address(bits);
// delay(100);
Serial.print("Node ID2: ");
Serial.println(nodeID2);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
//initialize the digital 13 pin as output
pinMode(led, OUTPUT);
// When the receiver is unstable and reboot, reading stored status from EEPROM
value = EEPROM.read(address);
if (value == '1')
{
digitalWrite(led, HIGH);
}
if (value == '0')
{
digitalWrite(led, LOW);
}
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
Serial.print(counter);
Serial.print(": ");
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
}
// if length of received message is less than transmitter sent meaning the receiver is unstable
if (messageLength < 4)
{
software_Reboot();
}
else
{
// netID and nodeID are numbers and message is charactor array, so convention is required
if ((message[0] == (netID + '0')) && (message[1] == (nodeID1 + '0')) && (message[2] == (nodeID2 + '0')))
{
if (message[3] == keyOn)
{
digitalWrite(led, HIGH);
EEPROM.write(address, '1');
}
else
{
if (message[3] == keyOff)
{
digitalWrite(led, LOW);
EEPROM.write(address, '0');
}
}
}
}
Serial.println();
counter++;
}
}
// Software reboot function
void software_Reboot()
{
wdt_enable(WDTO_15MS);
while (1)
{
}
}
//Create Net Address from DIP Switch (3 positions used A1-A3)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D2-D5)
byte node1Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode1[i])); // read the input pin
}
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D6-D9)
byte node2Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode2[i])); // read the input pin
}
return j; //return address
}
Sketch
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// This sketch uses VirtualWire
// Connect the Receiver data pin to Arduino pin 11
// Modified by Befun Hung on Oct. 29, 2014 by combining sketches on May. 11, 2014 (Arduino RF Wireless Message Display)
// and Jul. 30, 2014 (Use DIP Switch To Set Arduino Device Net ID And Node ID for Wireless Communication)
// and removing LCD Keypad Shield display function as a new sketch for Arduino addressable RF wireless power socket
// The sketch uses 3 analog pins(A1-A3) to set net ID and 8 digital pins(D2-D9) to set node ID by using 10K pull-up resistors.
// Totally 8x256=2,048 devices can be used for wireless communication
// When using a 3x4 telephone keypad, 8x10(0-9)=80 devices can be used
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D13 is used for singal output
#include <VirtualWire.h>
// include avr/wdt for watchdog reset
#include <avr/wdt.h>
// include <EEPROM.h> to save switch staus to EEPROM
#include <EEPROM.h>
// keys to turn switch on and off
#define keyOn '1'
#define keyOff '0'
//Create and Define Global Variables
int bits=8;
byte netID, nodeID;
int dipNet[] = {15, 16, 17}; //DIP Switch Pins for Net ID
int dipNode[] = {2, 3, 4, 5, 6, 7, 8, 9}; //DIP Switch Pins for Node ID
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
// digital pin 13 connected with a 1K resistor and a LED
int led = 13;
// Address of EEPROM for saving switch status and variable to store value
int address = 5;
int value;
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode[i], INPUT); // sets the digital pin 2-9 as input
}
nodeID = nodeAddress(bits);
Serial.print("Node ID: ");
Serial.println(nodeID);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
//initialize the digital 13 pin as output
pinMode(led, OUTPUT);
// When the receiver is unstable and reboot, reading stored status from EEPROM
value = EEPROM.read(address);
if (value == '1')
{
digitalWrite(led, HIGH);
}
if (value == '0')
{
digitalWrite(led, LOW);
}
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
Serial.print(counter);
Serial.print(": ");
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
}
// if length of received message is less than transmitter sent meaning the receiver is unstable
if (messageLength < 3)
{
software_Reboot();
}
else
{
// netID and nodeID are numbers and message is charactor array, so convention is required
if ((message[0] == (netID + '0')) && (message[1] == (nodeID + '0')))
{
if (message[2] == keyOn)
{
digitalWrite(led, HIGH);
EEPROM.write(address, '1');
}
else
{
if (message[2] == keyOff)
{
digitalWrite(led, LOW);
EEPROM.write(address, '0');
}
}
}
}
Serial.println();
counter++;
}
}
// Software reboot function
void software_Reboot()
{
wdt_enable(WDTO_15MS);
while (1)
{
}
}
//Create Net Address from DIP Switch (3 positions used)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node Address from DIP Switch (8 positions used D2 - D9)
byte nodeAddress(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode[i])); // read the input pin
}
return j; //return address
}
2014/09/21
Camera Slider / Dolly - MakerSlide + Arduino + CNC Shield + A4988 Driver + 42BYGH4417 Stepper Motor
One dimension movement is the most basic practice to position. By following the design of simple camera slider by Bart Dring from Inventables, I have made my own camera dolly and changed the pulley and belt of gt2 specification for easy steps calculation.
The use of CNC Shield is optional, it is used just for easy extension to y-axis and z-axis.
Connection
1. Stack CNC Shield on Arduino Uno or Mega2560
2. Connect CNC Shield to power supply with voltage 8-35V
3. Connect CNC X axis to 42BYGH4417 stepper motor
Photo
// simple stepper motor control
// only x axis is used for dolly
#define EN 8 / / stepper motor enable
#define X_DIR 5/ / x axis direction control
#define Y_DIR 6/ / y axis direction control
#define Z_DIR 7/ / z axis direction control
#define X_STP 2/ / x axis step control
#define Y_STP 3/ / y axis step control
#define Z_STP 4/ / z axis step control
/*
// step(): to control direction and steps of stepper motor
// parameter: dir for direction control,
// dirPin maps to DIR pin of stepper motor,
// stepperPin maps to STEP pin of stepper motor
// return value: none
*/
void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{
digitalWrite(dirPin, dir);
delay(50);
for (int i = 0; i < steps; i++) {
digitalWrite(stepperPin, HIGH);
delayMicroseconds(800);
digitalWrite(stepperPin, LOW);
delayMicroseconds(800);
}
}
void setup (){
// setup stepper motor I/O pin to output
pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
pinMode(EN, OUTPUT);
digitalWrite(EN, LOW);
}
void loop (){
// 200 steps per turn
step(false, X_DIR, X_STP, 1800); // run 360 mm
step(false, Y_DIR, Y_STP, 200);
step(false, Z_DIR, Z_STP, 200);
delay(1000);
step(true, X_DIR, X_STP, 1800); // run 360 mm in reverse direction
step(true, Y_DIR, Y_STP, 200);
step(true, Z_DIR, Z_STP, 200);
delay(1000);
}
The use of CNC Shield is optional, it is used just for easy extension to y-axis and z-axis.
Connection
1. Stack CNC Shield on Arduino Uno or Mega2560
2. Connect CNC Shield to power supply with voltage 8-35V
3. Connect CNC X axis to 42BYGH4417 stepper motor
Photo
Connections
Dolly In Motion
Sketch// simple stepper motor control
// only x axis is used for dolly
#define EN 8 / / stepper motor enable
#define X_DIR 5/ / x axis direction control
#define Y_DIR 6/ / y axis direction control
#define Z_DIR 7/ / z axis direction control
#define X_STP 2/ / x axis step control
#define Y_STP 3/ / y axis step control
#define Z_STP 4/ / z axis step control
/*
// step(): to control direction and steps of stepper motor
// parameter: dir for direction control,
// dirPin maps to DIR pin of stepper motor,
// stepperPin maps to STEP pin of stepper motor
// return value: none
*/
void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{
digitalWrite(dirPin, dir);
delay(50);
for (int i = 0; i < steps; i++) {
digitalWrite(stepperPin, HIGH);
delayMicroseconds(800);
digitalWrite(stepperPin, LOW);
delayMicroseconds(800);
}
}
void setup (){
// setup stepper motor I/O pin to output
pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
pinMode(EN, OUTPUT);
digitalWrite(EN, LOW);
}
void loop (){
// 200 steps per turn
step(false, X_DIR, X_STP, 1800); // run 360 mm
step(false, Y_DIR, Y_STP, 200);
step(false, Z_DIR, Z_STP, 200);
delay(1000);
step(true, X_DIR, X_STP, 1800); // run 360 mm in reverse direction
step(true, Y_DIR, Y_STP, 200);
step(true, Z_DIR, Z_STP, 200);
delay(1000);
}
Labels:
42BYGH4417,
A4988,
Arduino,
Camera,
CNC,
Dolly,
Driver,
MakerSlide,
Motor,
Shield,
Slider,
Stepper
2014/08/12
3x4 Keypad Radio Frequency remote control
To send digits to radio frequency receiver, a 3x4 keypad and a transmitter is a good combination. To use the keypad, the connection between keypad and pins has to be clarified. For my keypad, the connections are:
Keypad.1: Pin1 + Pin5
Keypad.2: Pin1 + Pin6
Keypad.3: Pin1 + Pin7
Keypad.4: Pin2 + Pin5
Keypad.5: Pin2 + Pin6
Keypad.6: Pin2 + Pin7
Keypad.7: Pin3 + Pin5
Keypad.8: Pin3 + Pin6
Keypad.9: Pin3 + Pin7
Keypad.*: Pin4 + Pin5
Keypad.0: Pin4 + Pin6
Keypad.#: Pin4 + Pin7
I just want to send 3 digits range from 000 to 999 to receiver running the sketch posted on May. 11, 2014. The result is showed on the following photo.
Connections
1. Transmitter.Vcc -> Arduino.5V
2. Transmitter.Gnd -> Arduino.Gnd
3. Transmitter.Data -> Arduino.D12
4. Keypad.Pin1 (ROW0) -> Arduino.D5
5. Keypad.Pin2 (ROW1) -> Arduino.D4
6. Keypad.Pin3 (ROW2) -> Arduino.D3
7. Keypad.Pin4 (ROW3) -> Arduino.D2
8. Keypad.Pin5 (COL0) -> Arduino.D8
9. Keypad.Pin6 (COL1) -> Arduino.D7
10. Keypad.Pin7 (COL2) -> Arduino.D6
Photo
Updated Sketch
// Modified by Befun Hung on Oct. 28, 2014
// Blink led after sending message to notice user 5 times
#include <Keypad.h>
#include <VirtualWire.h>
#define maxLength 3
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','#'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = {5, 4, 3, 2};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = {8, 7, 6}; // connect to the column pinouts of the keypad
char keyins[maxLength+1] = "";
int i=0, j=0, sendTimes=5;
int led=13;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
Serial.println("Ready!");
pinMode(led, OUTPUT);
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.print(key);
keyins[i] = key;
i++;
if (i == maxLength) {
for (j=0;j<sendTimes;j++) {
Serial.println();
send(keyins);
digitalWrite(led, HIGH);
delay(20);
digitalWrite(led, LOW);
delay(20);
}
i = 0;
}
}
}
void send(char *message)
{
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}
Sketch
#include <Keypad.h>
#include <VirtualWire.h>
#define maxLength 3
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','#'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = {5, 4, 3, 2};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = {8, 7, 6}; // connect to the column pinouts of the keypad
char keyins[maxLength+1] = "";
int i=0;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
Serial.println("Ready!");
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.print(key);
keyins[i] = key;
i++;
if (i == maxLength) {
Serial.println();
send(keyins);
i = 0;
}
}
}
void send(char *message)
{
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}
Keypad.1: Pin1 + Pin5
Keypad.2: Pin1 + Pin6
Keypad.3: Pin1 + Pin7
Keypad.4: Pin2 + Pin5
Keypad.5: Pin2 + Pin6
Keypad.6: Pin2 + Pin7
Keypad.7: Pin3 + Pin5
Keypad.8: Pin3 + Pin6
Keypad.9: Pin3 + Pin7
Keypad.*: Pin4 + Pin5
Keypad.0: Pin4 + Pin6
Keypad.#: Pin4 + Pin7
I just want to send 3 digits range from 000 to 999 to receiver running the sketch posted on May. 11, 2014. The result is showed on the following photo.
Connections
1. Transmitter.Vcc -> Arduino.5V
2. Transmitter.Gnd -> Arduino.Gnd
3. Transmitter.Data -> Arduino.D12
4. Keypad.Pin1 (ROW0) -> Arduino.D5
5. Keypad.Pin2 (ROW1) -> Arduino.D4
6. Keypad.Pin3 (ROW2) -> Arduino.D3
7. Keypad.Pin4 (ROW3) -> Arduino.D2
8. Keypad.Pin5 (COL0) -> Arduino.D8
9. Keypad.Pin6 (COL1) -> Arduino.D7
10. Keypad.Pin7 (COL2) -> Arduino.D6
Photo
Updated Sketch
// Modified by Befun Hung on Oct. 28, 2014
// Blink led after sending message to notice user 5 times
#include <Keypad.h>
#include <VirtualWire.h>
#define maxLength 3
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','#'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = {5, 4, 3, 2};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = {8, 7, 6}; // connect to the column pinouts of the keypad
char keyins[maxLength+1] = "";
int i=0, j=0, sendTimes=5;
int led=13;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
Serial.println("Ready!");
pinMode(led, OUTPUT);
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.print(key);
keyins[i] = key;
i++;
if (i == maxLength) {
for (j=0;j<sendTimes;j++) {
Serial.println();
send(keyins);
digitalWrite(led, HIGH);
delay(20);
digitalWrite(led, LOW);
delay(20);
}
i = 0;
}
}
}
void send(char *message)
{
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}
Sketch
#include <Keypad.h>
#include <VirtualWire.h>
#define maxLength 3
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','#'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = {5, 4, 3, 2};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = {8, 7, 6}; // connect to the column pinouts of the keypad
char keyins[maxLength+1] = "";
int i=0;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
Serial.println("Ready!");
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.print(key);
keyins[i] = key;
i++;
if (i == maxLength) {
Serial.println();
send(keyins);
i = 0;
}
}
}
void send(char *message)
{
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}
2014/08/09
Schematic and Photo Of Arduino PCF8574 I2C LCD Keypad Shield
My PCF8574 I2C LCD Keypad Shield has been completed. The benefit of I2C LCD Keypad Shield over LCD Keypad Shield is that it free up 6 digital I/O used by LCD Keypad Shield for other use.
The schematic used is version 1.1 other than the version 1.0 posted on Feb. 28, 2014. The difference between version 1.1 and version 1.0 is that the version 1.1 has a 4-pins I2C connector as shown on the bottom-left corner of the shield on the photo to act a either a shield or a breakout. When the shield serves as a breakout, the 5-way button cannot function. The sketch runs is same as the one posted on Feb. 28, 2014.
When the shield is stacked directly upon the Arduino Uno, it should be noticed avoiding the pins of PCF8574 touching the shield of USB type B connector of Arduino. A insulated stick is a simple way. It is recommend to use Arduino boards with mini or micro USB connector such as Leonardo or stack on any other shield.
Schematic
Photo
The schematic used is version 1.1 other than the version 1.0 posted on Feb. 28, 2014. The difference between version 1.1 and version 1.0 is that the version 1.1 has a 4-pins I2C connector as shown on the bottom-left corner of the shield on the photo to act a either a shield or a breakout. When the shield serves as a breakout, the 5-way button cannot function. The sketch runs is same as the one posted on Feb. 28, 2014.
When the shield is stacked directly upon the Arduino Uno, it should be noticed avoiding the pins of PCF8574 touching the shield of USB type B connector of Arduino. A insulated stick is a simple way. It is recommend to use Arduino boards with mini or micro USB connector such as Leonardo or stack on any other shield.
Schematic
Photo
2014/07/30
Use DIP Switch To Set Arduino Device Net ID And Node ID for Wireless Communication
To use one remote control to many switch radio frequency wireless power supply sockets, each one must has its unique ID to identify itself and act according commands received from the remote control.
In the example sketch,A2-A4 A1-A3 are set to 1, 0, 1; D2-D9 are set to 0,0,0,0,1,0,1,0. So the net ID is calculated as 1*4+0*2+1*1=5; node ID is calculated as 0*128+0*64+0*32+0*16+1*8+0*4+1*2+0*1=10.
Updated on Nov. 12, 2014
Use the same DIP setting above, the output will be :
Net ID: 5
Node ID1: 0
Node ID2:10
Photo of Connections
Output
Update Sketch (Nov. 12, 2014)
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// Modified by Befun Hung on Jul. 30, 2014 to use
// 3 analog pins(A1-A3) to set net ID
// 8 digital pins(D2-D9) to set Node ID by using 10K pull-up resistors.
// Totally 8x256=2,048 devices can be used for wireless communication
// For practical use 8x10=80 devices can be controlled using digital key of 3x4 telephone keypad
// Modified by Befun Hung on Nov. 12, 2014 to use
// 4 digital pins(D2-D5) to set node ID1 and
// 4 digital pins(D6-D9) to set node ID2 by using 10K pull-up resistors.
// Totally 8x16x16=2,048 devices can be used for wireless communication
// For practical use 8x10x10=800 devices can be controlled using digital key of 3x4 telephone keypad
// Wire and DIP switch connections from high bit to low bit are A1, A2, A3, D2, D3, D4, D5, D6, D7, D8 and D9
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D10-D13 are reserved for SPI
//Create and Define Global Variables
int bits=4, netID, nodeID1, nodeID2;
int dipNet[] = {15, 16, 17}; // DIP Switch Pins for Net ID
int dipNode1[] = {2, 3, 4, 5}; // DIP Switch Pins for Node ID1
int dipNode2[] = {6, 7, 8, 9}; // DIP Switch Pins for Node ID2
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
// delay(100);
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode1[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID1 = node1Address(bits);
// delay(100);
Serial.print("Node ID1: ");
Serial.println(nodeID1);
for(i = 0; i<bits; i++){
pinMode(dipNode2[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID2 = node2Address(bits);
// delay(100);
Serial.print("Node ID2: ");
Serial.println(nodeID2);
}
void loop()
{
}
//Create Net Address from DIP Switch (3 positions used A1-A3)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D2-D5)
byte node1Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode1[i])); // read the input pin
}
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D6-D9)
byte node2Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode2[i])); // read the input pin
}
return j; //return address
}
Sketch
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// Modified by Befun Hung on Jul. 30, 2014 to use 3 analog pins(A1-A3) to set net ID and 8 digital pins(D2-D9) to set node ID by using 10K pull-up resistors.
// Totally 8x256=2,048 devices can be used for wireless communication
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D10-D13 are reserved for SPI
//Create and Define Global Variables
int bits=8, netID, nodeID;
int dipNet[] = {15, 16, 17}; //DIP Switch Pins for Net ID
int dipNode[] = {2, 3, 4, 5, 6, 7, 8, 9}; //DIP Switch Pins for Node ID
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
// delay(100);
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode[i], INPUT); // sets the digital pin 2-9 as input
}
nodeID = nodeAddress(bits);
// delay(100);
Serial.print("Node ID: ");
Serial.println(nodeID);
}
void loop()
{
}
//Create Net Address from DIP Switch (3 positions used)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node Address from DIP Switch (8 positions used D2 - D9)
byte nodeAddress(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode[i])); // read the input pin
}
return j; //return address
}
In the example sketch,
Updated on Nov. 12, 2014
Use the same DIP setting above, the output will be :
Net ID: 5
Node ID1: 0
Node ID2:10
Photo of Connections
Output
Update Sketch (Nov. 12, 2014)
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// Modified by Befun Hung on Jul. 30, 2014 to use
// 3 analog pins(A1-A3) to set net ID
// 8 digital pins(D2-D9) to set Node ID by using 10K pull-up resistors.
// Totally 8x256=2,048 devices can be used for wireless communication
// For practical use 8x10=80 devices can be controlled using digital key of 3x4 telephone keypad
// Modified by Befun Hung on Nov. 12, 2014 to use
// 4 digital pins(D2-D5) to set node ID1 and
// 4 digital pins(D6-D9) to set node ID2 by using 10K pull-up resistors.
// Totally 8x16x16=2,048 devices can be used for wireless communication
// For practical use 8x10x10=800 devices can be controlled using digital key of 3x4 telephone keypad
// Wire and DIP switch connections from high bit to low bit are A1, A2, A3, D2, D3, D4, D5, D6, D7, D8 and D9
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D10-D13 are reserved for SPI
//Create and Define Global Variables
int bits=4, netID, nodeID1, nodeID2;
int dipNet[] = {15, 16, 17}; // DIP Switch Pins for Net ID
int dipNode1[] = {2, 3, 4, 5}; // DIP Switch Pins for Node ID1
int dipNode2[] = {6, 7, 8, 9}; // DIP Switch Pins for Node ID2
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
// delay(100);
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode1[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID1 = node1Address(bits);
// delay(100);
Serial.print("Node ID1: ");
Serial.println(nodeID1);
for(i = 0; i<bits; i++){
pinMode(dipNode2[i], INPUT); // sets the digital pin 2-5 as input
}
nodeID2 = node2Address(bits);
// delay(100);
Serial.print("Node ID2: ");
Serial.println(nodeID2);
}
void loop()
{
}
//Create Net Address from DIP Switch (3 positions used A1-A3)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D2-D5)
byte node1Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode1[i])); // read the input pin
}
return j; //return address
}
//Create Node1 Address from DIP Switch (4 positions used D6-D9)
byte node2Address(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode2[i])); // read the input pin
}
return j; //return address
}
Sketch
// Released by abocanegra on Dec. 11, 2009 using 4 pins, "DIP Switch 8 Position to Address Sensor" in Arduino Forum
// Modified by Befun Hung on Jul. 30, 2014 to use 3 analog pins(A1-A3) to set net ID and 8 digital pins(D2-D9) to set node ID by using 10K pull-up resistors.
// Totally 8x256=2,048 devices can be used for wireless communication
// A0 is reserved for analog sensor or digital sensor/actuator
// A4-A5 are reserved for I2C
// D0-D1 are reserved for RX/TX
// D10-D13 are reserved for SPI
//Create and Define Global Variables
int bits=8, netID, nodeID;
int dipNet[] = {15, 16, 17}; //DIP Switch Pins for Net ID
int dipNode[] = {2, 3, 4, 5, 6, 7, 8, 9}; //DIP Switch Pins for Node ID
void setup()
{
Serial.begin(9600);
int i;
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
netID = netAddress();
// delay(100);
Serial.print("Net ID: ");
Serial.println(netID);
for(i = 0; i<bits; i++){
pinMode(dipNode[i], INPUT); // sets the digital pin 2-9 as input
}
nodeID = nodeAddress(bits);
// delay(100);
Serial.print("Node ID: ");
Serial.println(nodeID);
}
void loop()
{
}
//Create Net Address from DIP Switch (3 positions used)
byte netAddress(){
int i,j=0;
//Get the switches state
j = (j << 1) | (! digitalRead(A1)); // read the input pin
j = (j << 1) | (! digitalRead(A2)); // read the input pin
j = (j << 1) | (! digitalRead(A3)); // read the input pin
return j; //return address
}
//Create Node Address from DIP Switch (8 positions used D2 - D9)
byte nodeAddress(int k){
int i,j=0;
//Get the switches state
for(i=0; i<k; i++){
j = (j << 1) | (! digitalRead(dipNode[i])); // read the input pin
}
return j; //return address
}
2014/06/22
Arduino Color LCD Shield Keypad Adjustable DS1307 Real Time Clock Using Time.h Library
The ColorLCDShield.h library comes with an example sketch ChronoLCD_Color which sets the time at compile stage and time cannot be adjusted. By reading time from DS1307, the sketch can get correct time after power interruption. By modifying the setTime(), time can be adjusted and restored to DS1307 real time clock. No re-compilation is needed any more.
Boards
1. Arduino Uno R3
2. cheaphousetek RTC Shield
3. Color LCD Shield
Photo
Sketch
/*
ChronoLCD Color - An example sketch for the Color LCD Shield Library
by: Jim Lindblom
SparkFun Electronics
date: 6/23/11
license: CC-BY SA 3.0 - Creative commons share-alike 3.0
use this code however you'd like, just keep this license and
attribute. Let me know if you make hugely, awesome, great changes.
This sketch draws an analog and digital clock on the Color LCD
Shield. You can also use the on-board buttons to set the hours
and minutes.
Use the defines at the top of the code to set the initial time.
You can also adjust the size and color of the clock.
To set the time, first hit S3. Then use S1 and S2 to adjust the
hours and minutes respsectively. Hit S3 to start the clock
back up.
This example code should give you a good idea of how to use
the setCircle, setLine, and setStr functions of the Color LCD
Shield Library.
*/
// Modified by Befun Hung on Jun. 22, 2014
// 1) Sync time with DS1307 real time clock
// 2) Use onboard keypad to adjust DS1307 time parameter
// Press S1 get into adjustment mode,
// Press S2 to adjust or
// Press S3 to select which parameter to be adjusted with default to hour
// Press S1 to save parameters to DS1307
// 3) Show date and weekday
// 4) Minor adjustment of analog clock
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
#include <ColorLCDShield.h>
char *dayOfWeek[] = {"", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
time_t t;
int displayAtSecond;
#define CLOCK_RADIUS 41 // radius of clock face
#define CLOCK_CENTER 50 // If you adjust the radius, you'll probably want to adjust this
#define H_LENGTH 23 // length of hour hand
#define M_LENGTH 33 // length of minute hand
#define S_LENGTH 37 // length of second hand
#define BACKGROUND BLACK // room for growth, adjust the background color according to daylight
#define C_COLOR RED // This is the color of the clock face, and digital clock
#define H_COLOR BLUE // hour hand color
#define M_COLOR GREEN // minute hand color
#define S_COLOR YELLOW // second hand color
LCDShield lcd;
int years, months, days;
int hours, minutes, seconds;
int buttonPins[3] = {3, 4, 5};
void setup()
{
/* Set up the button pins as inputs, set pull-up resistor */
for (int i=0; i<3; i++)
{
pinMode(buttonPins[i], INPUT);
digitalWrite(buttonPins[i], HIGH);
}
/* Initialize the LCD, set the contrast, clear the screen */
lcd.init(PHILIPS);
lcd.contrast(-63);
lcd.clear(BACKGROUND);
setSyncProvider(RTC.get); // the function to get the time from the RTC
}
void loop()
{
t = now();
years = year(t);
months = month(t);
days = day(t);
hours = hour(t);
minutes = minute(t);
seconds = second(t);
if (!digitalRead(buttonPins[2]))
setTime(); // If S3 was pressed, go set the time
if (displayAtSecond != second(t)) {
drawClock(); // Draw the clock face, this includes 12, 3, 6, 9
displayAnalogTime(hours, minutes, seconds); // Draw the clock hands
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds); // Draw the digital clock text
displayAtSecond = second(t);
}
}
/*
setTime uses on-shield switches S1, S2, and S3 to set the time
pressing S3 will exit the function. S1 increases hours, S2
increases seconds.
*/
void setTime()
{
int setVariable = 3, checkStatus = 0;
/* Reset the clock */
years = year(t);
months = month(t);
days = day(t);
hours = hour(t);
minutes = minute(t);
seconds = second(t);
/* Draw the clock, so we can see the new time */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
while (!digitalRead(buttonPins[2]))
; // wait till they let go of S1
/* We'll run around this loop until S3 is pressed again */
while(digitalRead(buttonPins[2]))
{
/* If S1 is pressed, we'll update the hours */
if (!digitalRead(buttonPins[0]))
{
delay(100);
setVariable = (setVariable + 1) % 6; // Select year, month, day, hour, minute, second to change, default is year
/* and update the clock, so we can see it */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
}
if (!digitalRead(buttonPins[1]))
{
delay(100);
switch (setVariable) {
case 0:{
years = ((years + 1) % 100) + 2000;
break;
}
case 1:{
months = (months % 12) + 1;
break;
}
case 2:{
days = (days % 31) + 1;
break;
}
case 3:{
hours = (hours + 1) % 24;
break;
}
case 4:{
minutes = (minutes + 1) % 60;
break;
}
case 5:{
seconds = (seconds + 1) % 60;
break;
}
}
// minutes++; // Increase minutes by 1
// if (minutes >= 60)
// minutes = 0; // If minutes is 60, set it back to 0
/* and update the clock, so we can see it */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
}
}
/* Once S3 is pressed, we'll exit, but not until it's released */
while(!digitalRead(buttonPins[2]))
;
if ((months == 1 || months == 3 || months == 5 || months == 7 || months == 8 || months == 10 || months == 12) && days <= 31) checkStatus = 1;
if ((months == 4 || months == 6 || months == 9 || months == 11) && days <=30) checkStatus = 1;
if ((months == 2 && (years % 4) == 0) && days <= 29) checkStatus = 1;
if ((months == 2 && (years % 4) != 0) && days <= 28) checkStatus = 1;
if (checkStatus) {
setTime(hours, minutes, seconds, days, months, years);
RTC.set(now());
}
}
/*
displayDateDayOfWeek() takes in values for years, months, days.
It'll print the date, day of week, in digital format, on the
bottom of the screen.
*/
void displayDateDayOfWeek(int y, int m, int d)
{
char dateChar[12];
sprintf(dateChar, "%.4d-%.2d-%.2d ", y, m, d);
/* Print the time on the clock */
lcd.setStr(dateChar, 90, 10,
C_COLOR, BACKGROUND);
lcd.setStr(dayOfWeek[weekday()], 90, 98,
C_COLOR, BACKGROUND);
}
/*
displayDigitalTime() takes in values for hours, minutes and
seconds. It'll print the time, in digital format, on the
bottom of the screen.
*/
void displayDigitalTime(int h, int m, int s)
{
char timeChar[10]; // adjust the number of characters to avoid odd display
sprintf(timeChar, "%.2d:%.2d:%.2d", h, m, s);
/* Print the time on the clock */
lcd.setStr(timeChar, 105, 26, C_COLOR, BACKGROUND);
}
/*
drawClock() simply draws the outer circle of the clock, and '12',
'3', '6', and '9'. Room for growth here, if you want to customize
your clock. Maybe add dashe marks, or even all 12 digits.
*/
void drawClock()
{
/* Draw the circle */
lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, C_COLOR);
/* Print 12, 3, 6, 9, a lot of arbitrary values are used here
for the coordinates. Just used trial and error to get them
into a nice position. */
lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, C_COLOR, BACKGROUND);
lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, C_COLOR, BACKGROUND);
lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, C_COLOR, BACKGROUND);
lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, C_COLOR, BACKGROUND);
}
/*
displayAnalogTime() draws the three clock hands in their proper
position. Room for growth here, I'd like to make the clock hands
arrow shaped, or at least thicker and more visible.
*/
void displayAnalogTime(int h, int m, int s)
{
double midHours; // this will be used to slightly adjust the hour hand
static int hx, hy, mx, my, sx, sy;
/* Adjust time to shift display 90 degrees ccw
this will turn the clock the same direction as text */
h -= 3;
m -= 15;
s -= 15;
if (h <= 0)
h += 12;
if (m < 0)
m += 60;
if (s < 0)
s += 60;
/* Delete old lines: */
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BACKGROUND); // delete second hand
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BACKGROUND); // delete minute hand
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BACKGROUND); // delete hour hand
/* Calculate and draw new lines: */
s = map(s, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
sx = S_LENGTH * sin(3.14 * ((double) s)/180); // woo trig!
sy = S_LENGTH * cos(3.14 * ((double) s)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, S_COLOR); // print second hand
m = map(m, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
mx = M_LENGTH * sin(3.14 * ((double) m)/180); // woo trig!
my = M_LENGTH * cos(3.14 * ((double) m)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, M_COLOR); // print minute hand
midHours = minutes/12; // midHours is used to set the hours hand to middling levels between whole hours
h *= 5; // Get hours and midhours to the same scale
h += midHours; // add hours and midhours
h = map(h, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
hx = H_LENGTH * sin(3.14 * ((double) h)/180); // woo trig!
hy = H_LENGTH * cos(3.14 * ((double) h)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR); // print hour hand
}
Boards
1. Arduino Uno R3
2. cheaphousetek RTC Shield
3. Color LCD Shield
Photo
Sketch
/*
ChronoLCD Color - An example sketch for the Color LCD Shield Library
by: Jim Lindblom
SparkFun Electronics
date: 6/23/11
license: CC-BY SA 3.0 - Creative commons share-alike 3.0
use this code however you'd like, just keep this license and
attribute. Let me know if you make hugely, awesome, great changes.
This sketch draws an analog and digital clock on the Color LCD
Shield. You can also use the on-board buttons to set the hours
and minutes.
Use the defines at the top of the code to set the initial time.
You can also adjust the size and color of the clock.
To set the time, first hit S3. Then use S1 and S2 to adjust the
hours and minutes respsectively. Hit S3 to start the clock
back up.
This example code should give you a good idea of how to use
the setCircle, setLine, and setStr functions of the Color LCD
Shield Library.
*/
// Modified by Befun Hung on Jun. 22, 2014
// 1) Sync time with DS1307 real time clock
// 2) Use onboard keypad to adjust DS1307 time parameter
// Press S1 get into adjustment mode,
// Press S2 to adjust or
// Press S3 to select which parameter to be adjusted with default to hour
// Press S1 to save parameters to DS1307
// 3) Show date and weekday
// 4) Minor adjustment of analog clock
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
#include <ColorLCDShield.h>
char *dayOfWeek[] = {"", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
time_t t;
int displayAtSecond;
#define CLOCK_RADIUS 41 // radius of clock face
#define CLOCK_CENTER 50 // If you adjust the radius, you'll probably want to adjust this
#define H_LENGTH 23 // length of hour hand
#define M_LENGTH 33 // length of minute hand
#define S_LENGTH 37 // length of second hand
#define BACKGROUND BLACK // room for growth, adjust the background color according to daylight
#define C_COLOR RED // This is the color of the clock face, and digital clock
#define H_COLOR BLUE // hour hand color
#define M_COLOR GREEN // minute hand color
#define S_COLOR YELLOW // second hand color
LCDShield lcd;
int years, months, days;
int hours, minutes, seconds;
int buttonPins[3] = {3, 4, 5};
void setup()
{
/* Set up the button pins as inputs, set pull-up resistor */
for (int i=0; i<3; i++)
{
pinMode(buttonPins[i], INPUT);
digitalWrite(buttonPins[i], HIGH);
}
/* Initialize the LCD, set the contrast, clear the screen */
lcd.init(PHILIPS);
lcd.contrast(-63);
lcd.clear(BACKGROUND);
setSyncProvider(RTC.get); // the function to get the time from the RTC
}
void loop()
{
t = now();
years = year(t);
months = month(t);
days = day(t);
hours = hour(t);
minutes = minute(t);
seconds = second(t);
if (!digitalRead(buttonPins[2]))
setTime(); // If S3 was pressed, go set the time
if (displayAtSecond != second(t)) {
drawClock(); // Draw the clock face, this includes 12, 3, 6, 9
displayAnalogTime(hours, minutes, seconds); // Draw the clock hands
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds); // Draw the digital clock text
displayAtSecond = second(t);
}
}
/*
setTime uses on-shield switches S1, S2, and S3 to set the time
pressing S3 will exit the function. S1 increases hours, S2
increases seconds.
*/
void setTime()
{
int setVariable = 3, checkStatus = 0;
/* Reset the clock */
years = year(t);
months = month(t);
days = day(t);
hours = hour(t);
minutes = minute(t);
seconds = second(t);
/* Draw the clock, so we can see the new time */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
while (!digitalRead(buttonPins[2]))
; // wait till they let go of S1
/* We'll run around this loop until S3 is pressed again */
while(digitalRead(buttonPins[2]))
{
/* If S1 is pressed, we'll update the hours */
if (!digitalRead(buttonPins[0]))
{
delay(100);
setVariable = (setVariable + 1) % 6; // Select year, month, day, hour, minute, second to change, default is year
/* and update the clock, so we can see it */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
}
if (!digitalRead(buttonPins[1]))
{
delay(100);
switch (setVariable) {
case 0:{
years = ((years + 1) % 100) + 2000;
break;
}
case 1:{
months = (months % 12) + 1;
break;
}
case 2:{
days = (days % 31) + 1;
break;
}
case 3:{
hours = (hours + 1) % 24;
break;
}
case 4:{
minutes = (minutes + 1) % 60;
break;
}
case 5:{
seconds = (seconds + 1) % 60;
break;
}
}
// minutes++; // Increase minutes by 1
// if (minutes >= 60)
// minutes = 0; // If minutes is 60, set it back to 0
/* and update the clock, so we can see it */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
}
}
/* Once S3 is pressed, we'll exit, but not until it's released */
while(!digitalRead(buttonPins[2]))
;
if ((months == 1 || months == 3 || months == 5 || months == 7 || months == 8 || months == 10 || months == 12) && days <= 31) checkStatus = 1;
if ((months == 4 || months == 6 || months == 9 || months == 11) && days <=30) checkStatus = 1;
if ((months == 2 && (years % 4) == 0) && days <= 29) checkStatus = 1;
if ((months == 2 && (years % 4) != 0) && days <= 28) checkStatus = 1;
if (checkStatus) {
setTime(hours, minutes, seconds, days, months, years);
RTC.set(now());
}
}
/*
displayDateDayOfWeek() takes in values for years, months, days.
It'll print the date, day of week, in digital format, on the
bottom of the screen.
*/
void displayDateDayOfWeek(int y, int m, int d)
{
char dateChar[12];
sprintf(dateChar, "%.4d-%.2d-%.2d ", y, m, d);
/* Print the time on the clock */
lcd.setStr(dateChar, 90, 10,
C_COLOR, BACKGROUND);
lcd.setStr(dayOfWeek[weekday()], 90, 98,
C_COLOR, BACKGROUND);
}
/*
displayDigitalTime() takes in values for hours, minutes and
seconds. It'll print the time, in digital format, on the
bottom of the screen.
*/
void displayDigitalTime(int h, int m, int s)
{
char timeChar[10]; // adjust the number of characters to avoid odd display
sprintf(timeChar, "%.2d:%.2d:%.2d", h, m, s);
/* Print the time on the clock */
lcd.setStr(timeChar, 105, 26, C_COLOR, BACKGROUND);
}
/*
drawClock() simply draws the outer circle of the clock, and '12',
'3', '6', and '9'. Room for growth here, if you want to customize
your clock. Maybe add dashe marks, or even all 12 digits.
*/
void drawClock()
{
/* Draw the circle */
lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, C_COLOR);
/* Print 12, 3, 6, 9, a lot of arbitrary values are used here
for the coordinates. Just used trial and error to get them
into a nice position. */
lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, C_COLOR, BACKGROUND);
lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, C_COLOR, BACKGROUND);
lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, C_COLOR, BACKGROUND);
lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, C_COLOR, BACKGROUND);
}
/*
displayAnalogTime() draws the three clock hands in their proper
position. Room for growth here, I'd like to make the clock hands
arrow shaped, or at least thicker and more visible.
*/
void displayAnalogTime(int h, int m, int s)
{
double midHours; // this will be used to slightly adjust the hour hand
static int hx, hy, mx, my, sx, sy;
/* Adjust time to shift display 90 degrees ccw
this will turn the clock the same direction as text */
h -= 3;
m -= 15;
s -= 15;
if (h <= 0)
h += 12;
if (m < 0)
m += 60;
if (s < 0)
s += 60;
/* Delete old lines: */
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BACKGROUND); // delete second hand
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BACKGROUND); // delete minute hand
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BACKGROUND); // delete hour hand
/* Calculate and draw new lines: */
s = map(s, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
sx = S_LENGTH * sin(3.14 * ((double) s)/180); // woo trig!
sy = S_LENGTH * cos(3.14 * ((double) s)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, S_COLOR); // print second hand
m = map(m, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
mx = M_LENGTH * sin(3.14 * ((double) m)/180); // woo trig!
my = M_LENGTH * cos(3.14 * ((double) m)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, M_COLOR); // print minute hand
midHours = minutes/12; // midHours is used to set the hours hand to middling levels between whole hours
h *= 5; // Get hours and midhours to the same scale
h += midHours; // add hours and midhours
h = map(h, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
hx = H_LENGTH * sin(3.14 * ((double) h)/180); // woo trig!
hy = H_LENGTH * cos(3.14 * ((double) h)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR); // print hour hand
}
Labels:
Adjust,
Adjustable,
Arduino,
Color,
DS1307,
Freeduino,
Keypad,
LCD,
Library,
Real Time Clock,
RTC,
Shield,
Time Library,
Time.h
2014/05/11
Arduino RF Wireless Message Display
As I am building the RF wireless power socket for home automation, I need a stand along tool to display any wireless received message. During the lab, I use Arduino serial monitor to monitor the message received once a second, error always happens at different time point as following screen shot shows. After disconnecting the Arduino Uno from PC to monitor message received by using LCD keypad shield as a stand along system, the error condition gone.
The RF wireless message display can be used to display the time on the NTP synchronized RTC clock (my projects during Aug 2013), so no additional time adjustment at display side is needed.
Parts Used
1. Arduino Uno R3
2. cheaphousetek LCD Keypad Shield
3. RF Receiver (described in Arduino Cookbook 14.1)
Connection
1. Stack LCD Key Keypad Upon Arduino Uno R3
2. RF Receiver Data Pin - Arduino Uno D11
3. RF Receiver Vcc - Arduino Uno 5V
4. RF Receiver Gnd - Arduino Uno Gnd
Photo
The sketch runs correctly with output to LCD shield for 247,610 times.
Sketch
/*
SimpleReceiveLCD
This sketch displays text strings received using VirtualWire
Connect the Receiver data pin to Arduino pin 11
*/
#include <VirtualWire.h>
// include the library code:
#include <LiquidCrystal.h>
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
lcd.clear();
Serial.begin(9600);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
lcd.clear();
Serial.print(counter);
Serial.print(": ");
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 0);
lcd.print(counter);
lcd.print(":");
lcd.setCursor(0,1);
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
lcd.print(char(message[i]));
}
Serial.println();
counter++;
}
}
The RF wireless message display can be used to display the time on the NTP synchronized RTC clock (my projects during Aug 2013), so no additional time adjustment at display side is needed.
Parts Used
1. Arduino Uno R3
2. cheaphousetek LCD Keypad Shield
3. RF Receiver (described in Arduino Cookbook 14.1)
Connection
1. Stack LCD Key Keypad Upon Arduino Uno R3
2. RF Receiver Data Pin - Arduino Uno D11
3. RF Receiver Vcc - Arduino Uno 5V
4. RF Receiver Gnd - Arduino Uno Gnd
Photo
The sketch runs correctly with output to LCD shield for 247,610 times.
Sketch
/*
SimpleReceiveLCD
This sketch displays text strings received using VirtualWire
Connect the Receiver data pin to Arduino pin 11
*/
#include <VirtualWire.h>
// include the library code:
#include <LiquidCrystal.h>
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
unsigned long counter = 1;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
lcd.clear();
Serial.begin(9600);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
lcd.clear();
Serial.print(counter);
Serial.print(": ");
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 0);
lcd.print(counter);
lcd.print(":");
lcd.setCursor(0,1);
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
lcd.print(char(message[i]));
}
Serial.println();
counter++;
}
}
Subscribe to:
Posts (Atom)