First publish
Apply to FNK0020
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(){
|
||||
printf("hello, world!\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**********************************************************************
|
||||
* Filename : Blink.c
|
||||
* Description : Make an led blinking.
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/06/07
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 0
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
//when initialize wiring successfully,print message to screen
|
||||
printf("wiringPi initialize successfully, GPIO %d(wiringPi pin)\n",ledPin);
|
||||
|
||||
pinMode(ledPin, OUTPUT);//Set the pin mode
|
||||
|
||||
while(1){
|
||||
digitalWrite(ledPin, HIGH); //led on
|
||||
printf("led on...\n");
|
||||
delay(1000);
|
||||
digitalWrite(ledPin, LOW); //led off
|
||||
printf("...led off\n");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : ButtonLED.c
|
||||
* Description : Controlling an led by button.
|
||||
* Author : freenove
|
||||
* modification: 2016/06/12
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 0 //define the ledPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pinMode(ledPin, OUTPUT); //Set ledPin output
|
||||
pinMode(buttonPin, INPUT);//Set buttonPin input
|
||||
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
|
||||
while(1){
|
||||
|
||||
if(digitalRead(buttonPin) == LOW){ //button has pressed down
|
||||
digitalWrite(ledPin, HIGH); //led on
|
||||
printf("led on...\n");
|
||||
}
|
||||
else { //button has released
|
||||
digitalWrite(ledPin, LOW); //led off
|
||||
printf("...led off\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**********************************************************************
|
||||
* Filename : Tablelamp.c
|
||||
* Description : a DIY MINI table lamp
|
||||
* Author : freenove
|
||||
* modification: 2016/06/13
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 0 //define the ledPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
int ledState=LOW; //store the State of led
|
||||
int buttonState=HIGH; //store the State of button
|
||||
int lastbuttonState=HIGH;//store the lastState of button
|
||||
long lastChangeTime; //store the change time of button state
|
||||
long captureTime=50; //set the button state stable time
|
||||
int reading;
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
printf("Program is starting...\n");
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT);
|
||||
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
|
||||
while(1){
|
||||
reading = digitalRead(buttonPin); //read the current state of button
|
||||
if( reading != lastbuttonState){ //if the button state has changed ,record the time point
|
||||
lastChangeTime = millis();
|
||||
}
|
||||
//if changing-state of the button last beyond the time we set,we considered that
|
||||
//the current button state is an effective change rather than a buffeting
|
||||
if(millis() - lastChangeTime > captureTime){
|
||||
//if button state is changed ,update the data.
|
||||
if(reading != buttonState){
|
||||
buttonState = reading;
|
||||
//if the state is low ,the action is pressing
|
||||
if(buttonState == LOW){
|
||||
printf("Button is pressed!\n");
|
||||
ledState = !ledState; //Turn the LED state .
|
||||
if(ledState){
|
||||
printf("turn on LED ...\n");
|
||||
}
|
||||
else {
|
||||
printf("turn off LED ...\n");
|
||||
}
|
||||
}
|
||||
//if the state is high ,the action is releasing
|
||||
else {
|
||||
printf("Button is released!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
digitalWrite(ledPin,ledState);
|
||||
lastbuttonState = reading;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
/**********************************************************************
|
||||
* Filename : LightWater.c
|
||||
* Description : Display 10 LEDBar Graph
|
||||
* Author : freenove
|
||||
* modification: 2016/06/13
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#define leds 10
|
||||
int pins[leds] = {0,1,2,3,4,5,6,8,9,10};
|
||||
void led_on(int n)//make led_n on
|
||||
{
|
||||
digitalWrite(n, LOW);
|
||||
}
|
||||
|
||||
void led_off(int n)//make led_n off
|
||||
{
|
||||
digitalWrite(n, HIGH);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
printf("Program is starting ... \n");
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
for(i=0;i<leds;i++){ //make leds pins' mode is output
|
||||
pinMode(pins[i], OUTPUT);
|
||||
}
|
||||
while(1){
|
||||
for(i=0;i<leds;i++){ //make led on from left to right
|
||||
led_on(pins[i]);
|
||||
delay(100);
|
||||
led_off(pins[i]);
|
||||
}
|
||||
for(i=leds-1;i>-1;i--){ //make led on from right to left
|
||||
led_on(pins[i]);
|
||||
delay(100);
|
||||
led_off(pins[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : BreathingLED.c
|
||||
* Description : A breathing LED
|
||||
* Author : freenove
|
||||
* modification: 2016/06/14
|
||||
**********************************************************************/
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 1 //Only GPIO18 can output PWM
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pinMode(ledPin, PWM_OUTPUT);//pwm output mode
|
||||
|
||||
while(1){
|
||||
for(i=0;i<1024;i++){
|
||||
pwmWrite(ledPin, i);
|
||||
delay(2);
|
||||
}
|
||||
delay(300);
|
||||
for(i=1023;i>=0;i--){
|
||||
pwmWrite(ledPin, i);
|
||||
delay(2);
|
||||
}
|
||||
delay(300);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**********************************************************************
|
||||
* Filename : ColorfulLED.c
|
||||
* Description : A auto flash ColorfulLED
|
||||
* Author : freenove
|
||||
* modification: 2016/06/14
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <softPwm.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPinRed 0
|
||||
#define ledPinGreen 1
|
||||
#define ledPinBlue 2
|
||||
|
||||
void ledInit(void)
|
||||
{
|
||||
softPwmCreate(ledPinRed, 0, 100);//Creat SoftPWM pin
|
||||
softPwmCreate(ledPinGreen,0, 100);
|
||||
softPwmCreate(ledPinBlue, 0, 100);
|
||||
}
|
||||
|
||||
void ledColorSet(int r_val, int g_val, int b_val)
|
||||
{
|
||||
softPwmWrite(ledPinRed, r_val);//Set the duty cycle
|
||||
softPwmWrite(ledPinGreen, g_val);
|
||||
softPwmWrite(ledPinBlue, b_val);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int r,g,b;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
printf("Program is starting ...\n");
|
||||
ledInit();
|
||||
|
||||
while(1){
|
||||
r=random()%100;//get a random in (0,100)
|
||||
g=random()%100;
|
||||
b=random()%100;
|
||||
ledColorSet(r,g,b);//set random as a duty cycle value
|
||||
printf("r=%d, g=%d, b=%d \n",r,g,b);
|
||||
delay(300);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : Doorbell.c
|
||||
* Description : Controlling an buzzer by button.
|
||||
* Author : freenove
|
||||
* modification: 2016/06/12
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define buzzerPin 0 //define the buzzerPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT);
|
||||
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
|
||||
while(1){
|
||||
|
||||
if(digitalRead(buttonPin) == LOW){ //button has pressed down
|
||||
digitalWrite(buzzerPin, HIGH); //buzzer on
|
||||
printf("buzzer on...\n");
|
||||
}
|
||||
else { //button has released
|
||||
digitalWrite(buzzerPin, LOW); //buzzer off
|
||||
printf("...buzzer off\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**********************************************************************
|
||||
* Filename : Alertor.c
|
||||
* Description : Alarm by button.
|
||||
* Author : freenove
|
||||
* modification: 2016/06/14
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softTone.h>
|
||||
#include <math.h>
|
||||
|
||||
#define buzzerPin 0 //define the buzzerPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
|
||||
void alertor(int pin){
|
||||
int x;
|
||||
double sinVal, toneVal;
|
||||
for(x=0;x<360;x++){ //frequency of the alarm along the sine wave change
|
||||
sinVal = sin(x * (M_PI / 180)); //calculate the sine value
|
||||
toneVal = 2000 + sinVal * 500; //Add to the resonant frequency with a Weighted
|
||||
softToneWrite(pin,toneVal); //output PWM
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
void stopAlertor(int pin){
|
||||
softToneWrite(pin,0);
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT);
|
||||
softToneCreate(buzzerPin);
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
|
||||
while(1){
|
||||
if(digitalRead(buttonPin) == LOW){ //button has pressed down
|
||||
alertor(buzzerPin); //buzzer on
|
||||
printf("alertor on...\n");
|
||||
}
|
||||
else { //button has released
|
||||
stopAlertor(buzzerPin); //buzzer off
|
||||
printf("...buzzer off\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
/**********************************************************************
|
||||
* Filename : PCF8591.c
|
||||
* Description : ADC and DAC
|
||||
* Author : freenove
|
||||
* modification: 2016/06/14
|
||||
**********************************************************************/
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
int main(void){
|
||||
int value;
|
||||
float voltage;
|
||||
wiringPiSetup();
|
||||
pcf8591Setup(pinbase,address);
|
||||
|
||||
while(1){
|
||||
value = analogRead(A0); //read A0 pin
|
||||
analogWrite(pinbase+0,value);
|
||||
voltage = (float)value / 255.0 * 3.3; // calculate voltage
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : Softlight.c
|
||||
* Description : Potentiometer control LED
|
||||
* Author : freenove
|
||||
* modification: 2016/06/18
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
#define ledPin 0
|
||||
int main(void){
|
||||
int value;
|
||||
float voltage;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
softPwmCreate(ledPin,0,100);
|
||||
pcf8591Setup(pinbase,address);
|
||||
|
||||
while(1){
|
||||
value = analogRead(A0); //read A0 pin
|
||||
softPwmWrite(ledPin,value*100/255);
|
||||
voltage = (float)value / 255.0 * 3.3; // calculate voltage
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,45 @@
|
||||
/**********************************************************************
|
||||
* Filename : ColorfulSoftlight.c
|
||||
* Description : Potentiometer control RGBLED
|
||||
* Author : freenove
|
||||
* modification: 2016/07/03
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
#define ledRedPin 3 //define 3 pins of RGBLED
|
||||
#define ledGreenPin 2
|
||||
#define ledBluePin 0
|
||||
int main(void){
|
||||
int val_Red,val_Green,val_Blue;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
softPwmCreate(ledRedPin,0,100); //creat 3 PMW output pins for RGBLED
|
||||
softPwmCreate(ledGreenPin,0,100);
|
||||
softPwmCreate(ledBluePin,0,100);
|
||||
pcf8591Setup(pinbase,address); //initialize PCF8591
|
||||
|
||||
while(1){
|
||||
val_Red = analogRead(A0); //read 3 potentiometers
|
||||
val_Green = analogRead(A1);
|
||||
val_Blue = analogRead(A2);
|
||||
softPwmWrite(ledRedPin,val_Red*100/255); //map the read value of potentiometers into PWM value and output it
|
||||
softPwmWrite(ledGreenPin,val_Green*100/255);
|
||||
softPwmWrite(ledBluePin,val_Blue*100/255);
|
||||
//print out the read ADC value
|
||||
printf("ADC value val_Red: %d ,\tval_Green: %d ,\tval_Blue: %d \n",val_Red,val_Green,val_Blue);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : Nightlamp.c
|
||||
* Description : Photoresistor control LED
|
||||
* Author : freenove
|
||||
* modification: 2016/06/18
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
#define ledPin 0
|
||||
int main(void){
|
||||
int value;
|
||||
float voltage;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
softPwmCreate(ledPin,0,100);
|
||||
pcf8591Setup(pinbase,address);
|
||||
|
||||
while(1){
|
||||
value = analogRead(A0); //read A0 pin
|
||||
softPwmWrite(ledPin,value*100/255);
|
||||
voltage = (float)value / 255.0 * 3.3; // calculate voltage
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : Thermometer.c
|
||||
* Description : A DIY Thermometer
|
||||
* Author : freenove
|
||||
* modification: 2016/06/20
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
int main(void){
|
||||
int adcValue;
|
||||
float tempK,tempC;
|
||||
float voltage,Rt;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pcf8591Setup(pinbase,address);
|
||||
while(1){
|
||||
adcValue = analogRead(A0); //read A0 pin
|
||||
voltage = (float)adcValue / 255.0 * 3.3; // calculate voltage
|
||||
Rt = 10 * voltage / (3.3 - voltage); //calculate resistance value of thermistor
|
||||
tempK = 1/(1/(273.15 + 25) + log(Rt/10)/3950.0); //calculate temperature (Kelvin)
|
||||
tempC = tempK -273.15; //calculate temperature (Celsius)
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV, \tTemperature : %.2fC\n",adcValue,voltage,tempC);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,40 @@
|
||||
/**********************************************************************
|
||||
* Filename : Joystick.c
|
||||
* Description : Read Joystick
|
||||
* Author : freenove
|
||||
* modification: 2016/07/04
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
#define Z_Pin 1 //define pin for axis Z
|
||||
|
||||
int main(void){
|
||||
int val_X,val_Y,val_Z;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(Z_Pin,INPUT); //set Z_Pin as input pin and pull-up mode
|
||||
pullUpDnControl(Z_Pin,PUD_UP);
|
||||
pcf8591Setup(pinbase,address); //initialize PCF8591
|
||||
|
||||
while(1){
|
||||
val_Z = digitalRead(Z_Pin); //read digital quality of axis Z
|
||||
val_Y = analogRead(A1); //read analog quality of axis X and Y
|
||||
val_X = analogRead(A2);
|
||||
printf("val_X: %d ,\tval_Y: %d ,\tval_Z: %d \n",val_X,val_Y,val_Z);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,69 @@
|
||||
/**********************************************************************
|
||||
* Filename : Motor.c
|
||||
* Description : Control Motor by L293D
|
||||
* Author : freenove
|
||||
* modification: 2016/06/18
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8591.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define address 0x48 //pcf8591 default address
|
||||
#define pinbase 64 //any number above 64
|
||||
#define A0 pinbase + 0
|
||||
#define A1 pinbase + 1
|
||||
#define A2 pinbase + 2
|
||||
#define A3 pinbase + 3
|
||||
|
||||
#define motorPin1 2 //define the pin connected to L293D
|
||||
#define motorPin2 0
|
||||
#define enablePin 3
|
||||
//Map function: map the value from a range of mapping to another range.
|
||||
long map(long value,long fromLow,long fromHigh,long toLow,long toHigh){
|
||||
return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow;
|
||||
}
|
||||
//motor function: determine the direction and speed of the motor according to the ADC
|
||||
void motor(int ADC){
|
||||
int value = ADC -128;
|
||||
if(value>0){
|
||||
digitalWrite(motorPin1,HIGH);
|
||||
digitalWrite(motorPin2,LOW);
|
||||
printf("turn Forward...\n");
|
||||
}
|
||||
else if (value<0){
|
||||
digitalWrite(motorPin1,LOW);
|
||||
digitalWrite(motorPin2,HIGH);
|
||||
printf("turn Back...\n");
|
||||
}
|
||||
else {
|
||||
digitalWrite(motorPin1,LOW);
|
||||
digitalWrite(motorPin2,LOW);
|
||||
printf("Motor Stop...\n");
|
||||
}
|
||||
softPwmWrite(enablePin,map(abs(value),0,128,0,255));
|
||||
printf("The PWM duty cycle is %d%%\n",abs(value)*100/127);//print the PMW duty cycle
|
||||
}
|
||||
int main(void){
|
||||
int value;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(enablePin,OUTPUT);//set mode for the pin
|
||||
pinMode(motorPin1,OUTPUT);
|
||||
pinMode(motorPin2,OUTPUT);
|
||||
softPwmCreate(enablePin,0,100);//define PMW pin
|
||||
pcf8591Setup(pinbase,address);//initialize PCF8591
|
||||
|
||||
while(1){
|
||||
value = analogRead(A0); //read A0 pin
|
||||
printf("ADC value : %d \n",value);
|
||||
motor(value); //start the motor
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
/**********************************************************************
|
||||
* Filename : Relay.c
|
||||
* Description : Button control Relay and Motor
|
||||
* Author : freenove
|
||||
* modification: 2016/07/05
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define relayPin 0 //define the relayPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
int relayState=LOW; //store the State of relay
|
||||
int buttonState=HIGH; //store the State of button
|
||||
int lastbuttonState=HIGH;//store the lastState of button
|
||||
long lastChangeTime; //store the change time of button state
|
||||
long captureTime=50; //set the button state stable time
|
||||
int reading;
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring fairelay,print messageto screen
|
||||
printf("setup wiringPi fairelay !");
|
||||
return 1;
|
||||
}
|
||||
printf("Program is starting...\n");
|
||||
pinMode(relayPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT);
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
|
||||
while(1){
|
||||
reading = digitalRead(buttonPin); //read the current state of button
|
||||
if( reading != lastbuttonState){ //if the button state has changed ,record the time point
|
||||
lastChangeTime = millis();
|
||||
}
|
||||
//if changing-state of the button last beyond the time we set,we considered that
|
||||
//the current button state is an effective change rather than a buffeting
|
||||
if(millis() - lastChangeTime > captureTime){
|
||||
//if button state is changed ,update the data.
|
||||
if(reading != buttonState){
|
||||
buttonState = reading;
|
||||
//if the state is low ,the action is pressing
|
||||
if(buttonState == LOW){
|
||||
printf("Button is pressed!\n");
|
||||
relayState = !relayState;
|
||||
if(relayState){
|
||||
printf("turn on relay ...\n");
|
||||
}
|
||||
else {
|
||||
printf("turn off relay ...\n");
|
||||
}
|
||||
}
|
||||
//if the state is high ,the action is releasing
|
||||
else {
|
||||
printf("Button is released!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
digitalWrite(relayPin,relayState);
|
||||
lastbuttonState = reading;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
/**********************************************************************
|
||||
* Filename : Sweep.c
|
||||
* Description : Servo sweep
|
||||
* Author : freenove
|
||||
* modification: 2016/07/05
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <softPwm.h>
|
||||
#include <stdio.h>
|
||||
#define OFFSET_MS 3 //Define the unit of servo pulse offset: 0.1ms
|
||||
#define SERVO_MIN_MS 5+OFFSET_MS //define the pulse duration for minimum angle of servo
|
||||
#define SERVO_MAX_MS 25+OFFSET_MS //define the pulse duration for maximum angle of servo
|
||||
|
||||
#define servoPin 1 //define the GPIO number connected to servo
|
||||
long map(long value,long fromLow,long fromHigh,long toLow,long toHigh){
|
||||
return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow;
|
||||
}
|
||||
void servoInit(int pin){ //initialization function for servo PMW pin
|
||||
softPwmCreate(pin, 0, 200);
|
||||
}
|
||||
void servoWrite(int pin, int angle){ //Specif a certain rotation angle (0-180) for the servo
|
||||
if(angle > 180)
|
||||
angle = 180;
|
||||
if(angle < 0)
|
||||
angle = 0;
|
||||
softPwmWrite(pin,map(angle,0,180,SERVO_MIN_MS,SERVO_MAX_MS));
|
||||
}
|
||||
void servoWriteMS(int pin, int ms){ //specific the unit for pulse(5-25ms) with specific duration output by servo pin: 0.1ms
|
||||
if(ms > SERVO_MAX_MS)
|
||||
ms = SERVO_MAX_MS;
|
||||
if(ms < SERVO_MIN_MS)
|
||||
ms = SERVO_MIN_MS;
|
||||
softPwmWrite(pin,ms);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring faiservo,print messageto screen
|
||||
printf("setup wiringPi faiservo !");
|
||||
return 1;
|
||||
}
|
||||
printf("Program is starting ...\n");
|
||||
servoInit(servoPin); //initialize PMW pin of servo
|
||||
while(1){
|
||||
for(i=SERVO_MIN_MS;i<SERVO_MAX_MS;i++){ //make servo rotate from minimum angle to maximum angle
|
||||
servoWriteMS(servoPin,i);
|
||||
delay(10);
|
||||
}
|
||||
delay(500);
|
||||
for(i=SERVO_MAX_MS;i>SERVO_MIN_MS;i--){ //make servo rotate from maximum angle to minimum angle
|
||||
servoWriteMS(servoPin,i);
|
||||
delay(10);
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
/**********************************************************************
|
||||
* Filename : SteppingMotor.c
|
||||
* Description :
|
||||
* Author : freenove
|
||||
* modification: 2016/07/07
|
||||
**********************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
const int motorPins[]={1,4,5,6}; //define pins connected to four phase ABCD of stepper motor
|
||||
const int CCWStep[]={0x01,0x02,0x04,0x08}; //define power supply order for coil for rotating anticlockwise
|
||||
const int CWStep[]={0x08,0x04,0x02,0x01}; //define power supply order for coil for rotating clockwise
|
||||
//as for four phase stepping motor, four steps is a cycle. the function is used to drive the stepping motor clockwise or anticlockwise to take four steps
|
||||
void moveOnePeriod(int dir,int ms){
|
||||
int i=0,j=0;
|
||||
for (j=0;j<4;j++){ //cycle according to power supply order
|
||||
for (i=0;i<4;i++){ //assign to each pin, a total of 4 pins
|
||||
if(dir == 1) //power supply order clockwise
|
||||
digitalWrite(motorPins[i],(CCWStep[j] == (1<<i)) ? HIGH : LOW);
|
||||
else //power supply order anticlockwise
|
||||
digitalWrite(motorPins[i],(CWStep[j] == (1<<i)) ? HIGH : LOW);
|
||||
printf("motorPin %d, %d \n",motorPins[i],digitalRead(motorPins[i]));
|
||||
}
|
||||
printf("Step cycle!\n");
|
||||
if(ms<3) //the delay can not be less than 3ms, otherwise it will exceed speed limit of the motor
|
||||
ms=3;
|
||||
delay(ms);
|
||||
}
|
||||
}
|
||||
//continuous rotation function, the parameter steps specifies the rotation cycles, every four steps is a cycle
|
||||
void moveSteps(int dir, int ms, int steps){
|
||||
int i;
|
||||
for(i=0;i<steps;i++){
|
||||
moveOnePeriod(dir,ms);
|
||||
}
|
||||
}
|
||||
void motorStop(){ //function used to stop rotating
|
||||
int i;
|
||||
for(i=0;i<4;i++){
|
||||
digitalWrite(motorPins[i],LOW);
|
||||
}
|
||||
}
|
||||
int main(void){
|
||||
int i;
|
||||
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
for(i=0;i<4;i++){
|
||||
pinMode(motorPins[i],OUTPUT);
|
||||
}
|
||||
|
||||
while(1){
|
||||
moveSteps(1,3,512); //rotating 360° clockwise, a total of 2048 steps in a circle, namely, 512 cycles.
|
||||
delay(500);
|
||||
moveSteps(0,3,512); //rotating 360° anticlockwise
|
||||
delay(500);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
/**********************************************************************
|
||||
* Filename : LightWater02.c
|
||||
* Description : Control LED by 74HC595
|
||||
* Author : freenove
|
||||
* modification: 2016/06/21
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringShift.h>
|
||||
|
||||
#define dataPin 0 //DS Pin of 74HC595(Pin14)
|
||||
#define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
|
||||
#define clockPin 3 //CH_CP Pin of 74HC595(Pin11)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char x;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(dataPin,OUTPUT);
|
||||
pinMode(latchPin,OUTPUT);
|
||||
pinMode(clockPin,OUTPUT);
|
||||
while(1){
|
||||
x=0x01;
|
||||
for(i=0;i<8;i++){
|
||||
digitalWrite(latchPin,LOW); // Output low level to latchPin
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,x);// Send serial data to 74HC595
|
||||
digitalWrite(latchPin,HIGH); // Output high level to latchPin, and 74HC595 will update the data to the parallel output port.
|
||||
x<<=1; // make the variable move one bit to left once, then the bright LED move one step to the left once.
|
||||
delay(100);
|
||||
}
|
||||
x=0x80;
|
||||
for(i=0;i<8;i++){
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,x);
|
||||
digitalWrite(latchPin,HIGH);
|
||||
x>>=1;
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
/**********************************************************************
|
||||
* Filename : SevenSegmentDisplay.c
|
||||
* Description : Control SevenSegmentDisplay by 74HC595
|
||||
* Author : freenove
|
||||
* modification: 2016/06/24
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringShift.h>
|
||||
|
||||
#define dataPin 0 //DS Pin of 74HC595(Pin14)
|
||||
#define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
|
||||
#define clockPin 3 //CH_CP Pin of 74HC595(Pin11)
|
||||
//encoding for character 0-F of common anode SevenSegmentDisplay.
|
||||
unsigned char num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(dataPin,OUTPUT);
|
||||
pinMode(latchPin,OUTPUT);
|
||||
pinMode(clockPin,OUTPUT);
|
||||
while(1){
|
||||
for(i=0;i<sizeof(num);i++){
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,num[i]);//Output the figures and the highest level is transfered preferentially.
|
||||
digitalWrite(latchPin,HIGH);
|
||||
delay(500);
|
||||
}
|
||||
for(i=0;i<sizeof(num);i++){
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,num[i] & 0x7f);//Use the "&0x7f" to display the decimal point.
|
||||
digitalWrite(latchPin,HIGH);
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**********************************************************************
|
||||
* Filename : StopWatch.c
|
||||
* Description : Control 4_Digit_7_Segment_Display by 74HC595
|
||||
* Author : freenove
|
||||
* modification: 2016/07/07
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringShift.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#define dataPin 5 //DS Pin of 74HC595(Pin14)
|
||||
#define latchPin 4 //ST_CP Pin of 74HC595(Pin12)
|
||||
#define clockPin 1 //CH_CP Pin of 74HC595(Pin11)
|
||||
const int digitPin[]={0,2,3,12}; // Define 7-segment display common pin
|
||||
// character 0-9 code of common anode 7-segment display
|
||||
unsigned char num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
|
||||
int counter = 0; //variable counter,the number will be displayed by 7-segment display
|
||||
//Open one of the 7-segment display and close the remaining three, the parameter digit is optional for 1,2,4,8
|
||||
void selectDigit(int digit){
|
||||
digitalWrite(digitPin[0],((digit&0x08) == 0x08) ? LOW : HIGH);
|
||||
digitalWrite(digitPin[1],((digit&0x04) == 0x04) ? LOW : HIGH);
|
||||
digitalWrite(digitPin[2],((digit&0x02) == 0x02) ? LOW : HIGH);
|
||||
digitalWrite(digitPin[3],((digit&0x01) == 0x01) ? LOW : HIGH);
|
||||
}
|
||||
void outData(int8_t data){ //function used to output data for 74HC595输出数据函数
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,data);
|
||||
digitalWrite(latchPin,HIGH);
|
||||
}
|
||||
void display(int dec){ //display function for 7-segment display
|
||||
selectDigit(0x01); //select the first, and display the single digit
|
||||
outData(num[dec%10]);
|
||||
delay(1); //display duration
|
||||
selectDigit(0x02); //select the second, and display the tens digit
|
||||
outData(num[dec%100/10]);
|
||||
delay(1);
|
||||
selectDigit(0x04); //select the third, and display the hundreds digit
|
||||
outData(num[dec%1000/100]);
|
||||
delay(1);
|
||||
selectDigit(0x08); //select the fourth, and display the thousands digit
|
||||
outData(num[dec%10000/1000]);
|
||||
delay(1);
|
||||
}
|
||||
void timer(int sig){ //Timer function
|
||||
if(sig == SIGALRM){ //If the signal is SIGALRM, the value of counter plus 1, and update the number displayed by 7-segment display
|
||||
counter ++;
|
||||
alarm(1); //set the next timer time
|
||||
printf("counter : %d \n",counter);
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(dataPin,OUTPUT); //set the pin connected to74HC595 for output mode
|
||||
pinMode(latchPin,OUTPUT);
|
||||
pinMode(clockPin,OUTPUT);
|
||||
//set the pin connected to 7-segment display common end to output mode
|
||||
for(i=0;i<4;i++){
|
||||
pinMode(digitPin[i],OUTPUT);
|
||||
digitalWrite(digitPin[i],LOW);
|
||||
}
|
||||
signal(SIGALRM,timer); //configure the timer
|
||||
alarm(1); //set the time of timer to 1s
|
||||
while(1){
|
||||
display(counter); //display the number counter
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
|
||||
0x00, 0x00, 0x21, 0x7F, 0x01, 0x00, 0x00, 0x00, // "1"
|
||||
0x00, 0x00, 0x23, 0x45, 0x49, 0x31, 0x00, 0x00, // "2"
|
||||
0x00, 0x00, 0x22, 0x49, 0x49, 0x36, 0x00, 0x00, // "3"
|
||||
0x00, 0x00, 0x0E, 0x32, 0x7F, 0x02, 0x00, 0x00, // "4"
|
||||
0x00, 0x00, 0x79, 0x49, 0x49, 0x46, 0x00, 0x00, // "5"
|
||||
0x00, 0x00, 0x3E, 0x49, 0x49, 0x26, 0x00, 0x00, // "6"
|
||||
0x00, 0x00, 0x60, 0x47, 0x48, 0x70, 0x00, 0x00, // "7"
|
||||
0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, // "8"
|
||||
0x00, 0x00, 0x32, 0x49, 0x49, 0x3E, 0x00, 0x00, // "9"
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x3E, 0x00, 0x00, // "0"
|
||||
0x00, 0x00, 0x3F, 0x44, 0x44, 0x3F, 0x00, 0x00, // "A"
|
||||
0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00, // "B"
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x22, 0x00, 0x00, // "C"
|
||||
0x00, 0x00, 0x7F, 0x41, 0x41, 0x3E, 0x00, 0x00, // "D"
|
||||
0x00, 0x00, 0x7F, 0x49, 0x49, 0x41, 0x00, 0x00, // "E"
|
||||
0x00, 0x00, 0x7F, 0x48, 0x48, 0x40, 0x00, 0x00 // "F"
|
||||
Binary file not shown.
@@ -0,0 +1,77 @@
|
||||
/**********************************************************************
|
||||
* Filename : LEDMatrix.c
|
||||
* Description : Control LEDMatrix by 74HC595
|
||||
* Author : freenove
|
||||
* modification: 2016/06/24
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringShift.h>
|
||||
|
||||
#define dataPin 0 //DS Pin of 74HC595(Pin14)
|
||||
#define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
|
||||
#define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
|
||||
// data of smiling face
|
||||
unsigned char pic[]={0x1c,0x22,0x51,0x45,0x45,0x51,0x22,0x1c};
|
||||
unsigned char data[]={ // data of "0-F"
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x3E, 0x00, 0x00, // "0"
|
||||
0x00, 0x00, 0x21, 0x7F, 0x01, 0x00, 0x00, 0x00, // "1"
|
||||
0x00, 0x00, 0x23, 0x45, 0x49, 0x31, 0x00, 0x00, // "2"
|
||||
0x00, 0x00, 0x22, 0x49, 0x49, 0x36, 0x00, 0x00, // "3"
|
||||
0x00, 0x00, 0x0E, 0x32, 0x7F, 0x02, 0x00, 0x00, // "4"
|
||||
0x00, 0x00, 0x79, 0x49, 0x49, 0x46, 0x00, 0x00, // "5"
|
||||
0x00, 0x00, 0x3E, 0x49, 0x49, 0x26, 0x00, 0x00, // "6"
|
||||
0x00, 0x00, 0x60, 0x47, 0x48, 0x70, 0x00, 0x00, // "7"
|
||||
0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, // "8"
|
||||
0x00, 0x00, 0x32, 0x49, 0x49, 0x3E, 0x00, 0x00, // "9"
|
||||
0x00, 0x00, 0x3F, 0x44, 0x44, 0x3F, 0x00, 0x00, // "A"
|
||||
0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00, // "B"
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x22, 0x00, 0x00, // "C"
|
||||
0x00, 0x00, 0x7F, 0x41, 0x41, 0x3E, 0x00, 0x00, // "D"
|
||||
0x00, 0x00, 0x7F, 0x49, 0x49, 0x41, 0x00, 0x00, // "E"
|
||||
0x00, 0x00, 0x7F, 0x48, 0x48, 0x40, 0x00, 0x00, // "F"
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
|
||||
};
|
||||
int main(void)
|
||||
{
|
||||
int i,j,k;
|
||||
unsigned char x;
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(dataPin,OUTPUT);
|
||||
pinMode(latchPin,OUTPUT);
|
||||
pinMode(clockPin,OUTPUT);
|
||||
while(1){
|
||||
for(j=0;j<500;j++){// Repeat enough times to display the smiling face a period of time
|
||||
x=0x80;
|
||||
for(i=0;i<8;i++){
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,pic[i]);// first shift data of line information to the first stage 74HC959
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,~x);//then shift data of column information to the second stage 74HC959
|
||||
|
||||
digitalWrite(latchPin,HIGH);//Output data of two stage 74HC595 at the same time
|
||||
x>>=1;// display the next column
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
for(k=0;k<sizeof(data)-8;k++){ //sizeof(data) total number of "0-F" columns
|
||||
for(j=0;j<20;j++){// times of repeated displaying LEDMatrix in every frame, the bigger the “j”, the longer the display time
|
||||
x=0x80; // Set the column information to start from the first column
|
||||
for(i=k;i<8+k;i++){
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,data[i]);
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,~x);
|
||||
digitalWrite(latchPin,HIGH);
|
||||
x>>=1;
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**********************************************************************
|
||||
* Filename : I2CLCD1602.c
|
||||
* Description : Use the LCD display data
|
||||
* Author : freenove
|
||||
* modification: 2016/06/25
|
||||
**********************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringPi.h>
|
||||
#include <pcf8574.h>
|
||||
#include <lcd.h>
|
||||
#include <time.h>
|
||||
|
||||
#define pcf8574_address 0x27 // default I2C address of Pcf8574
|
||||
#define BASE 64 // BASE is not less than 64
|
||||
//////// Define the output pins of the PCF8574, which are directly connected to the LCD1602 pin.
|
||||
#define RS BASE+0
|
||||
#define RW BASE+1
|
||||
#define EN BASE+2
|
||||
#define LED BASE+3
|
||||
#define D4 BASE+4
|
||||
#define D5 BASE+5
|
||||
#define D6 BASE+6
|
||||
#define D7 BASE+7
|
||||
|
||||
int lcdhd;// used to handle LCD
|
||||
void printCPUTemperature(){// sub function used to print CPU temperature
|
||||
FILE *fp;
|
||||
char str_temp[15];
|
||||
float CPU_temp;
|
||||
// CPU temperature data is stored in this directory.
|
||||
fp=fopen("/sys/class/thermal/thermal_zone0/temp","r");
|
||||
fgets(str_temp,15,fp); // read file temp
|
||||
CPU_temp = atof(str_temp)/1000.0; // convert to Celsius degrees
|
||||
printf("CPU's temperature : %.2f \n",CPU_temp);
|
||||
lcdPosition(lcdhd,0,0); // set the LCD cursor position to (0,0)
|
||||
lcdPrintf(lcdhd,"CPU:%.2fC",CPU_temp);// Display CPU temperature on LCD
|
||||
fclose(fp);
|
||||
}
|
||||
void printDataTime(){//used to print system time
|
||||
time_t rawtime;
|
||||
struct tm *timeinfo;
|
||||
time(&rawtime);// get system time
|
||||
timeinfo = localtime(&rawtime);// convert to local time
|
||||
printf("%s \n",asctime(timeinfo));
|
||||
lcdPosition(lcdhd,0,1);// set the LCD cursor position to (0,1)
|
||||
lcdPrintf(lcdhd,"Time:%d:%d:%d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
|
||||
//Display system time on LCD
|
||||
}
|
||||
int main(void){
|
||||
int i;
|
||||
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pcf8574Setup(BASE,pcf8574_address);// initialize PCF8574
|
||||
for(i=0;i<8;i++){
|
||||
pinMode(BASE+i,OUTPUT); // set PCF8574 port to output mode
|
||||
}
|
||||
digitalWrite(LED,HIGH); // turn on LCD backlight
|
||||
digitalWrite(RW,LOW); // allow writing to LCD
|
||||
lcdhd = lcdInit(2,16,4,RS,EN,D4,D5,D6,D7,0,0,0,0);// initialize LCD and return “handle” used to handle LCD
|
||||
if(lcdhd == -1){
|
||||
printf("lcdInit failed !");
|
||||
return 1;
|
||||
}
|
||||
while(1){
|
||||
printCPUTemperature();// print CPU temperature
|
||||
printDataTime(); // print system time
|
||||
delay(1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
/**********************************************************************
|
||||
* Filename : DHT.cpp
|
||||
* Description : DHT Temperature & Humidity Sensor library for Raspberry
|
||||
* Author : freenove
|
||||
* modification: 2016/07/10
|
||||
**********************************************************************/
|
||||
#include "DHT.hpp"
|
||||
//Function: Read DHT sensor, store the original data in bits[]
|
||||
// return values:DHTLIB_OK DHTLIB_ERROR_CHECKSUM DHTLIB_ERROR_TIMEOUT
|
||||
int DHT::readSensor(int pin,int wakeupDelay){
|
||||
int mask = 0x80;
|
||||
int idx = 0;
|
||||
int i ;
|
||||
int32_t t;
|
||||
for (i=0;i<5;i++){
|
||||
bits[i] = 0;
|
||||
}
|
||||
pinMode(pin,OUTPUT);
|
||||
digitalWrite(pin,LOW);
|
||||
delay(wakeupDelay);
|
||||
digitalWrite(pin,HIGH);
|
||||
delayMicroseconds(40);
|
||||
pinMode(pin,INPUT);
|
||||
|
||||
int loopCnt = DHTLIB_TIMEOUT;
|
||||
t = micros();
|
||||
while(digitalRead(pin)==LOW){
|
||||
if((micros() - t) > loopCnt){
|
||||
return DHTLIB_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
loopCnt = DHTLIB_TIMEOUT;
|
||||
t = micros();
|
||||
while(digitalRead(pin)==HIGH){
|
||||
if((micros() - t) > loopCnt){
|
||||
return DHTLIB_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
for (i = 0; i<40;i++){
|
||||
loopCnt = DHTLIB_TIMEOUT;
|
||||
t = micros();
|
||||
while(digitalRead(pin)==LOW){
|
||||
if((micros() - t) > loopCnt)
|
||||
return DHTLIB_ERROR_TIMEOUT;
|
||||
}
|
||||
t = micros();
|
||||
loopCnt = DHTLIB_TIMEOUT;
|
||||
while(digitalRead(pin)==HIGH){
|
||||
if((micros() - t) > loopCnt){
|
||||
return DHTLIB_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
if((micros() - t ) > 60){
|
||||
bits[idx] |= mask;
|
||||
}
|
||||
mask >>= 1;
|
||||
if(mask == 0){
|
||||
mask = 0x80;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
pinMode(pin,OUTPUT);
|
||||
digitalWrite(pin,HIGH);
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
//Function:Read DHT sensor, analyze the data of temperature and humidity
|
||||
//return:DHTLIB_OK DHTLIB_ERROR_CHECKSUM DHTLIB_ERROR_TIMEOUT
|
||||
int DHT::readDHT11(int pin){
|
||||
int rv ;
|
||||
int8_t sum;
|
||||
rv = readSensor(pin,DHTLIB_DHT11_WAKEUP);
|
||||
if(rv != DHTLIB_OK){
|
||||
humidity = DHTLIB_INVALID_VALUE;
|
||||
temperature = DHTLIB_INVALID_VALUE;
|
||||
return rv;
|
||||
}
|
||||
humidity = bits[0];
|
||||
temperature = bits[2];
|
||||
sum = bits[0] + bits[2];
|
||||
if(bits[4] != sum)
|
||||
return DHTLIB_ERROR_CHECKSUM;
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : DHT.hpp
|
||||
* Description : DHT Temperature & Humidity Sensor library for Raspberry
|
||||
* Author : freenove
|
||||
* modification: 2016/07/10
|
||||
**********************************************************************/
|
||||
#ifndef _DHT_H_
|
||||
#define _DHT_H_
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
////read return flag of sensor
|
||||
#define DHTLIB_OK 0
|
||||
#define DHTLIB_ERROR_CHECKSUM -1
|
||||
#define DHTLIB_ERROR_TIMEOUT -2
|
||||
#define DHTLIB_INVALID_VALUE -999
|
||||
|
||||
#define DHTLIB_DHT11_WAKEUP 18
|
||||
#define DHTLIB_DHT_WAKEUP 1
|
||||
|
||||
#define DHTLIB_TIMEOUT 100
|
||||
|
||||
class DHT{
|
||||
public:
|
||||
double humidity,temperature; //use to store temperature and humidity data read
|
||||
int readDHT11(int pin); //read DHT11
|
||||
private:
|
||||
int bits[5]; //Buffer to receiver data
|
||||
int readSensor(int pin,int wakeupDelay); //
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,44 @@
|
||||
/**********************************************************************
|
||||
* Filename : DHT11.cpp
|
||||
* Description : read the temperature and humidity data of DHT11
|
||||
* Author : freenove
|
||||
* modification: 2016/07/10
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "DHT.hpp"
|
||||
|
||||
#define DHT11_Pin 0 //define the pin of sensor
|
||||
|
||||
int main(){
|
||||
DHT dht; //create a DHT class object
|
||||
int chk,sumCnt;//chk:read the return value of sensor; sumCnt:times of reading sensor
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
while(1){
|
||||
chk = dht.readDHT11(DHT11_Pin); //read DHT11 and get a return value. Then determine whether data read is normal according to the return value.
|
||||
sumCnt++; //counting number of reading times
|
||||
printf("The sumCnt is : %d \n",sumCnt);
|
||||
switch(chk){
|
||||
case DHTLIB_OK: //if the return value is DHTLIB_OK, the data is normal.
|
||||
printf("DHT11,OK! \n");
|
||||
break;
|
||||
case DHTLIB_ERROR_CHECKSUM: //data check has errors
|
||||
printf("DHTLIB_ERROR_CHECKSUM! \n");
|
||||
break;
|
||||
case DHTLIB_ERROR_TIMEOUT: //reading DHT times out
|
||||
printf("DHTLIB_ERROR_TIMEOUT! \n");
|
||||
break;
|
||||
case DHTLIB_INVALID_VALUE: //other errors
|
||||
printf("DHTLIB_INVALID_VALUE! \n");
|
||||
break;
|
||||
}
|
||||
printf("Humidity is %.2f %%, \t Temperature is %.2f *C\n\n",dht.humidity,dht.temperature);
|
||||
delay(1000);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|| @file Key.cpp
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include "Key.hpp"
|
||||
|
||||
|
||||
// default constructor
|
||||
Key::Key() {
|
||||
kchar = NO_KEY;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
// constructor
|
||||
Key::Key(char userKeyChar) {
|
||||
kchar = userKeyChar;
|
||||
kcode = -1;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
|
||||
void Key::key_update (char userKeyChar, KeyState userState, boolean userStatus) {
|
||||
kchar = userKeyChar;
|
||||
kstate = userState;
|
||||
stateChanged = userStatus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
||
|
||||
|| @file Key.h
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEY_H
|
||||
#define KEY_H
|
||||
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define boolean bool
|
||||
#define byte unsigned char
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef enum{ IDLE, PRESSED, HOLD, RELEASED } KeyState;
|
||||
|
||||
const char NO_KEY = '\0';
|
||||
|
||||
class Key {
|
||||
public:
|
||||
// members
|
||||
char kchar;
|
||||
int kcode;
|
||||
KeyState kstate;
|
||||
boolean stateChanged;
|
||||
|
||||
// methods
|
||||
Key();
|
||||
Key(char userKeyChar);
|
||||
void key_update(char userKeyChar, KeyState userState, boolean userStatus);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.cpp
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include "Keypad.hpp"
|
||||
|
||||
// <<constructor>> Allows custom keymap, pin configuration, and keypad sizes.
|
||||
Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols) {
|
||||
rowPins = row;
|
||||
columnPins = col;
|
||||
sizeKpd.rows = numRows;
|
||||
sizeKpd.columns = numCols;
|
||||
|
||||
begin(userKeymap);
|
||||
|
||||
setDebounceTime(50);
|
||||
setHoldTime(500);
|
||||
keypadEventListener = 0;
|
||||
|
||||
startTime = 0;
|
||||
single_key = false;
|
||||
}
|
||||
|
||||
// Let the user define a keymap - assume the same row/column count as defined in constructor
|
||||
void Keypad::begin(char *userKeymap) {
|
||||
keymap = userKeymap;
|
||||
}
|
||||
|
||||
// Returns a single key only. Retained for backwards compatibility.
|
||||
char Keypad::getKey() {
|
||||
single_key = true;
|
||||
if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED)){
|
||||
return key[0].kchar;
|
||||
}
|
||||
|
||||
single_key = false;
|
||||
return NO_KEY;
|
||||
}
|
||||
|
||||
// Populate the key list.
|
||||
bool Keypad::getKeys() {
|
||||
bool keyActivity = false;
|
||||
|
||||
// Limit how often the keypad is scanned. This makes the loop() run 10 times as fast.
|
||||
if ( (millis()-startTime)>debounceTime ) {
|
||||
scanKeys();
|
||||
keyActivity = updateList();
|
||||
startTime = millis();
|
||||
}
|
||||
return keyActivity;
|
||||
}
|
||||
|
||||
// Private : Hardware scan
|
||||
void Keypad::scanKeys() {
|
||||
// Re-intialize the row pins. Allows sharing these pins with other hardware.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
pin_mode(rowPins[r],INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// bitMap stores ALL the keys that are being pressed.
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
pin_mode(columnPins[c],OUTPUT);
|
||||
pin_write(columnPins[c], LOW); // Begin column pulse output.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
bitWrite(bitMap[r], c, !pin_read(rowPins[r])); // keypress is active low so invert to high.
|
||||
}
|
||||
// Set pin to high impedance input. Effectively ends column pulse.
|
||||
pin_write(columnPins[c],HIGH);
|
||||
pin_mode(columnPins[c],INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
|
||||
bool Keypad::updateList() {
|
||||
bool anyActivity = false;
|
||||
|
||||
// Delete any IDLE keys
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kstate==IDLE) {
|
||||
key[i].kchar = NO_KEY;
|
||||
key[i].kcode = -1;
|
||||
key[i].stateChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new keys to empty slots in the key list.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
boolean button = bitRead(bitMap[r],c);
|
||||
char keyChar = keymap[r * sizeKpd.columns + c];
|
||||
int keyCode = r * sizeKpd.columns + c;
|
||||
int idx = findInList (keyCode);
|
||||
// Key is already on the list so set its next state.
|
||||
if (idx > -1) {
|
||||
nextKeyState(idx, button);
|
||||
}
|
||||
// Key is NOT on the list so add it.
|
||||
if ((idx == -1) && button) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar==NO_KEY) { // Find an empty slot or don't add key to list.
|
||||
key[i].kchar = keyChar;
|
||||
key[i].kcode = keyCode;
|
||||
key[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
|
||||
nextKeyState (i, button);
|
||||
break; // Don't fill all the empty slots with the same key.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report if the user changed the state of any key.
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].stateChanged) anyActivity = true;
|
||||
}
|
||||
return anyActivity;
|
||||
}
|
||||
|
||||
// Private
|
||||
// This function is a state machine but is also used for debouncing the keys.
|
||||
void Keypad::nextKeyState(byte idx, boolean button) {
|
||||
key[idx].stateChanged = false;
|
||||
switch (key[idx].kstate) {
|
||||
case IDLE:
|
||||
if (button==CLOSED) {
|
||||
transitionTo (idx, PRESSED);
|
||||
holdTimer = millis(); } // Get ready for next HOLD state.
|
||||
break;
|
||||
case PRESSED:
|
||||
if ((millis()-holdTimer)>holdTime) // Waiting for a key HOLD...
|
||||
transitionTo (idx, HOLD);
|
||||
else if (button==OPEN) // or for a key to be RELEASED.
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case HOLD:
|
||||
if (button==OPEN){
|
||||
|
||||
transitionTo (idx, RELEASED);
|
||||
}
|
||||
break;
|
||||
case RELEASED:
|
||||
transitionTo (idx, IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// New in 2.1
|
||||
bool Keypad::isPressed(char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if ( key[i].kchar == keyChar ) {
|
||||
if ( (key[i].kstate == PRESSED) && key[i].stateChanged )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Not pressed.
|
||||
}
|
||||
|
||||
// Search by character for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar == keyChar) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search by code for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (int keyCode) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kcode == keyCode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// New in 2.0
|
||||
char Keypad::waitForKey() {
|
||||
char waitKey = NO_KEY;
|
||||
while( (waitKey = getKey()) == NO_KEY ); // Block everything while waiting for a keypress.
|
||||
return waitKey;
|
||||
}
|
||||
|
||||
// Backwards compatibility function.
|
||||
KeyState Keypad::getState() {
|
||||
return key[0].kstate;
|
||||
}
|
||||
|
||||
// The end user can test for any changes in state before deciding
|
||||
// if any variables, etc. needs to be updated in their code.
|
||||
bool Keypad::keyStateChanged() {
|
||||
return key[0].stateChanged;
|
||||
}
|
||||
|
||||
// The number of keys on the key list, key[LIST_MAX], equals the number
|
||||
// of bytes in the key list divided by the number of bytes in a Key object.
|
||||
byte Keypad::numKeys() {
|
||||
return sizeof(key)/sizeof(Key);
|
||||
}
|
||||
|
||||
// Minimum debounceTime is 1 mS. Any lower *will* slow down the loop().
|
||||
void Keypad::setDebounceTime(uint debounce) {
|
||||
debounce<1 ? debounceTime=1 : debounceTime=debounce;
|
||||
}
|
||||
|
||||
void Keypad::setHoldTime(uint hold) {
|
||||
holdTime = hold;
|
||||
}
|
||||
|
||||
void Keypad::addEventListener(void (*listener)(char)){
|
||||
keypadEventListener = listener;
|
||||
}
|
||||
|
||||
void Keypad::transitionTo(byte idx, KeyState nextState) {
|
||||
key[idx].kstate = nextState;
|
||||
key[idx].stateChanged = true;
|
||||
|
||||
// Sketch used the getKey() function.
|
||||
// Calls keypadEventListener only when the first key in slot 0 changes state.
|
||||
if (single_key) {
|
||||
if ( (keypadEventListener!=NULL) && (idx==0) ) {
|
||||
keypadEventListener(key[0].kchar);
|
||||
}
|
||||
}
|
||||
// Sketch used the getKeys() function.
|
||||
// Calls keypadEventListener on any key that changes state.
|
||||
else {
|
||||
if (keypadEventListener!=NULL) {
|
||||
keypadEventListener(key[idx].kchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pin_mode(byte pinNum, byte mode) {
|
||||
if(mode == INPUT_PULLUP) {
|
||||
pinMode(pinNum, INPUT);
|
||||
pullUpDnControl(pinNum,PUD_UP);
|
||||
}
|
||||
else{
|
||||
pinMode(pinNum, mode);
|
||||
}
|
||||
}
|
||||
void pin_write(byte pinNum, boolean level) {
|
||||
digitalWrite(pinNum, level);
|
||||
}
|
||||
int pin_read(byte pinNum) {
|
||||
return digitalRead(pinNum);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.h
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEYPAD_H
|
||||
#define KEYPAD_H
|
||||
|
||||
#include "Key.hpp"
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//#define NULL '\0'
|
||||
#define INPUT_PULLUP 0x02
|
||||
#define bitWrite(x,n,b) (b ? (x |= 1<<n) : (x &= ~(1<<n)))
|
||||
#define bitRead(x,n) ((((x>>n)&1) == 1) ? 1 : 0)
|
||||
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef char KeypadEvent;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
// Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0
|
||||
// by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :)
|
||||
typedef struct {
|
||||
byte rows;
|
||||
byte columns;
|
||||
} KeypadSize;
|
||||
|
||||
#define LIST_MAX 10 // Max number of keys on the active list.
|
||||
#define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns)
|
||||
#define makeKeymap(x) ((char*)x)
|
||||
|
||||
|
||||
//class Keypad : public Key, public HAL_obj {
|
||||
class Keypad : public Key {
|
||||
public:
|
||||
|
||||
Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
|
||||
|
||||
uint bitMap[MAPSIZE]; // 10 row x 16 column array of bits. Except Due which has 32 columns.
|
||||
Key key[LIST_MAX];
|
||||
unsigned long holdTimer;
|
||||
|
||||
char getKey();
|
||||
bool getKeys();
|
||||
KeyState getState();
|
||||
void begin(char *userKeymap);
|
||||
bool isPressed(char keyChar);
|
||||
void setDebounceTime(uint);
|
||||
void setHoldTime(uint);
|
||||
void addEventListener(void (*listener)(char));
|
||||
int findInList(char keyChar);
|
||||
int findInList(int keyCode);
|
||||
char waitForKey();
|
||||
bool keyStateChanged();
|
||||
byte numKeys();
|
||||
|
||||
private:
|
||||
unsigned long startTime;
|
||||
char *keymap;
|
||||
byte *rowPins;
|
||||
byte *columnPins;
|
||||
KeypadSize sizeKpd;
|
||||
uint debounceTime;
|
||||
uint holdTime;
|
||||
bool single_key;
|
||||
|
||||
void scanKeys();
|
||||
bool updateList();
|
||||
void nextKeyState(byte n, boolean button);
|
||||
void transitionTo(byte n, KeyState nextState);
|
||||
void (*keypadEventListener)(char);
|
||||
};
|
||||
|
||||
//#define __PIN_MODE__PINWRITE__PINREAD__
|
||||
void pin_mode(byte pinNum, byte mode);
|
||||
void pin_write(byte pinNum, boolean level);
|
||||
int pin_read(byte pinNum);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added test to determine which header file to compile,
|
||||
|| | WProgram.h or Arduino.h.
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes
|
||||
|| | the keypadEventListener will trigger, if set
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.cpp
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include "Keypad.hpp"
|
||||
|
||||
// <<constructor>> Allows custom keymap, pin configuration, and keypad sizes.
|
||||
Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols) {
|
||||
rowPins = row;
|
||||
columnPins = col;
|
||||
sizeKpd.rows = numRows;
|
||||
sizeKpd.columns = numCols;
|
||||
|
||||
begin(userKeymap);
|
||||
|
||||
setDebounceTime(10);
|
||||
setHoldTime(500);
|
||||
keypadEventListener = 0;
|
||||
|
||||
startTime = 0;
|
||||
single_key = false;
|
||||
}
|
||||
|
||||
// Let the user define a keymap - assume the same row/column count as defined in constructor
|
||||
void Keypad::begin(char *userKeymap) {
|
||||
keymap = userKeymap;
|
||||
}
|
||||
|
||||
// Returns a single key only. Retained for backwards compatibility.
|
||||
char Keypad::getKey() {
|
||||
single_key = true;
|
||||
|
||||
if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED))
|
||||
return key[0].kchar;
|
||||
|
||||
single_key = false;
|
||||
|
||||
return NO_KEY;
|
||||
}
|
||||
|
||||
// Populate the key list.
|
||||
bool Keypad::getKeys() {
|
||||
bool keyActivity = false;
|
||||
|
||||
// Limit how often the keypad is scanned. This makes the loop() run 10 times as fast.
|
||||
if ( (millis()-startTime)>debounceTime ) {
|
||||
scanKeys();
|
||||
keyActivity = updateList();
|
||||
startTime = millis();
|
||||
}
|
||||
|
||||
return keyActivity;
|
||||
}
|
||||
|
||||
// Private : Hardware scan
|
||||
void Keypad::scanKeys() {
|
||||
// Re-intialize the row pins. Allows sharing these pins with other hardware.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
pin_mode(rowPins[r],INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// bitMap stores ALL the keys that are being pressed.
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
pin_mode(columnPins[c],OUTPUT);
|
||||
pin_write(columnPins[c], LOW); // Begin column pulse output.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
bitWrite(bitMap[r], c, !pin_read(rowPins[r])); // keypress is active low so invert to high.
|
||||
}
|
||||
// Set pin to high impedance input. Effectively ends column pulse.
|
||||
pin_write(columnPins[c],HIGH);
|
||||
pin_mode(columnPins[c],INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
|
||||
bool Keypad::updateList() {
|
||||
|
||||
bool anyActivity = false;
|
||||
|
||||
// Delete any IDLE keys
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kstate==IDLE) {
|
||||
key[i].kchar = NO_KEY;
|
||||
key[i].kcode = -1;
|
||||
key[i].stateChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new keys to empty slots in the key list.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
boolean button = bitRead(bitMap[r],c);
|
||||
char keyChar = keymap[r * sizeKpd.columns + c];
|
||||
int keyCode = r * sizeKpd.columns + c;
|
||||
int idx = findInList (keyCode);
|
||||
// Key is already on the list so set its next state.
|
||||
if (idx > -1) {
|
||||
nextKeyState(idx, button);
|
||||
}
|
||||
// Key is NOT on the list so add it.
|
||||
if ((idx == -1) && button) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar==NO_KEY) { // Find an empty slot or don't add key to list.
|
||||
key[i].kchar = keyChar;
|
||||
key[i].kcode = keyCode;
|
||||
key[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
|
||||
nextKeyState (i, button);
|
||||
break; // Don't fill all the empty slots with the same key.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report if the user changed the state of any key.
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].stateChanged) anyActivity = true;
|
||||
}
|
||||
|
||||
return anyActivity;
|
||||
}
|
||||
|
||||
// Private
|
||||
// This function is a state machine but is also used for debouncing the keys.
|
||||
void Keypad::nextKeyState(byte idx, boolean button) {
|
||||
key[idx].stateChanged = false;
|
||||
|
||||
switch (key[idx].kstate) {
|
||||
case IDLE:
|
||||
if (button==CLOSED) {
|
||||
transitionTo (idx, PRESSED);
|
||||
holdTimer = millis(); } // Get ready for next HOLD state.
|
||||
break;
|
||||
case PRESSED:
|
||||
if ((millis()-holdTimer)>holdTime) // Waiting for a key HOLD...
|
||||
transitionTo (idx, HOLD);
|
||||
else if (button==OPEN) // or for a key to be RELEASED.
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case HOLD:
|
||||
if (button==OPEN)
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case RELEASED:
|
||||
transitionTo (idx, IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// New in 2.1
|
||||
bool Keypad::isPressed(char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if ( key[i].kchar == keyChar ) {
|
||||
if ( (key[i].kstate == PRESSED) && key[i].stateChanged )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Not pressed.
|
||||
}
|
||||
|
||||
// Search by character for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar == keyChar) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search by code for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (int keyCode) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kcode == keyCode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// New in 2.0
|
||||
char Keypad::waitForKey() {
|
||||
char waitKey = NO_KEY;
|
||||
while( (waitKey = getKey()) == NO_KEY ); // Block everything while waiting for a keypress.
|
||||
return waitKey;
|
||||
}
|
||||
|
||||
// Backwards compatibility function.
|
||||
KeyState Keypad::getState() {
|
||||
return key[0].kstate;
|
||||
}
|
||||
|
||||
// The end user can test for any changes in state before deciding
|
||||
// if any variables, etc. needs to be updated in their code.
|
||||
bool Keypad::keyStateChanged() {
|
||||
return key[0].stateChanged;
|
||||
}
|
||||
|
||||
// The number of keys on the key list, key[LIST_MAX], equals the number
|
||||
// of bytes in the key list divided by the number of bytes in a Key object.
|
||||
byte Keypad::numKeys() {
|
||||
return sizeof(key)/sizeof(Key);
|
||||
}
|
||||
|
||||
// Minimum debounceTime is 1 mS. Any lower *will* slow down the loop().
|
||||
void Keypad::setDebounceTime(uint debounce) {
|
||||
debounce<1 ? debounceTime=1 : debounceTime=debounce;
|
||||
}
|
||||
|
||||
void Keypad::setHoldTime(uint hold) {
|
||||
holdTime = hold;
|
||||
}
|
||||
|
||||
void Keypad::addEventListener(void (*listener)(char)){
|
||||
keypadEventListener = listener;
|
||||
}
|
||||
|
||||
void Keypad::transitionTo(byte idx, KeyState nextState) {
|
||||
key[idx].kstate = nextState;
|
||||
key[idx].stateChanged = true;
|
||||
|
||||
// Sketch used the getKey() function.
|
||||
// Calls keypadEventListener only when the first key in slot 0 changes state.
|
||||
if (single_key) {
|
||||
if ( (keypadEventListener!=NULL) && (idx==0) ) {
|
||||
keypadEventListener(key[0].kchar);
|
||||
}
|
||||
}
|
||||
// Sketch used the getKeys() function.
|
||||
// Calls keypadEventListener on any key that changes state.
|
||||
else {
|
||||
if (keypadEventListener!=NULL) {
|
||||
keypadEventListener(key[idx].kchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added decision logic to compile WProgram.h or Arduino.h
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Every time a state changes the keypadEventListener will trigger, if set.
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime. setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.h
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEYPAD_H
|
||||
#define KEYPAD_H
|
||||
|
||||
#include "utility/Key.hpp"
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define NULL 0
|
||||
#define INPUT_PULLUP 0x02
|
||||
#define bitWrite(x,n,b) (b ? (x |= b<<n) : (x &= ~(b<<n)))
|
||||
#define bitRead(x,n) ((((x>>n)&1) == 1) ? 1 : 0)
|
||||
|
||||
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef char KeypadEvent;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
// Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0
|
||||
// by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :)
|
||||
typedef struct {
|
||||
byte rows;
|
||||
byte columns;
|
||||
} KeypadSize;
|
||||
|
||||
#define LIST_MAX 10 // Max number of keys on the active list.
|
||||
#define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns)
|
||||
#define makeKeymap(x) ((char*)x)
|
||||
|
||||
|
||||
//class Keypad : public Key, public HAL_obj {
|
||||
class Keypad : public Key {
|
||||
public:
|
||||
|
||||
Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
|
||||
|
||||
virtual void pin_mode(byte pinNum, byte mode) {
|
||||
if(mode == INPUT_PULLUP) {
|
||||
pinMode(pinNum, INPUT);
|
||||
pullUpDnControl(pinNum,PUD_UP);
|
||||
}
|
||||
else{
|
||||
pinMode(pinNum, mode);
|
||||
}
|
||||
}
|
||||
virtual void pin_write(byte pinNum, boolean level) { digitalWrite(pinNum, level); }
|
||||
virtual int pin_read(byte pinNum) { return digitalRead(pinNum); }
|
||||
|
||||
uint bitMap[MAPSIZE]; // 10 row x 16 column array of bits. Except Due which has 32 columns.
|
||||
Key key[LIST_MAX];
|
||||
unsigned long holdTimer;
|
||||
|
||||
char getKey();
|
||||
bool getKeys();
|
||||
KeyState getState();
|
||||
void begin(char *userKeymap);
|
||||
bool isPressed(char keyChar);
|
||||
void setDebounceTime(uint);
|
||||
void setHoldTime(uint);
|
||||
void addEventListener(void (*listener)(char));
|
||||
int findInList(char keyChar);
|
||||
int findInList(int keyCode);
|
||||
char waitForKey();
|
||||
bool keyStateChanged();
|
||||
byte numKeys();
|
||||
|
||||
private:
|
||||
unsigned long startTime;
|
||||
char *keymap;
|
||||
byte *rowPins;
|
||||
byte *columnPins;
|
||||
KeypadSize sizeKpd;
|
||||
uint debounceTime;
|
||||
uint holdTime;
|
||||
bool single_key;
|
||||
|
||||
void scanKeys();
|
||||
bool updateList();
|
||||
void nextKeyState(byte n, boolean button);
|
||||
void transitionTo(byte n, KeyState nextState);
|
||||
void (*keypadEventListener)(char);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added test to determine which header file to compile,
|
||||
|| | WProgram.h or Arduino.h.
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes
|
||||
|| | the keypadEventListener will trigger, if set
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
# Keypad Library data types
|
||||
KeyState KEYWORD1
|
||||
Keypad KEYWORD1
|
||||
KeypadEvent KEYWORD1
|
||||
|
||||
# Keypad Library constants
|
||||
NO_KEY LITERAL1
|
||||
IDLE LITERAL1
|
||||
PRESSED LITERAL1
|
||||
HOLD LITERAL1
|
||||
RELEASED LITERAL1
|
||||
|
||||
# Keypad Library methods & functions
|
||||
addEventListener KEYWORD2
|
||||
bitMap KEYWORD2
|
||||
findKeyInList KEYWORD2
|
||||
getKey KEYWORD2
|
||||
getKeys KEYWORD2
|
||||
getState KEYWORD2
|
||||
holdTimer KEYWORD2
|
||||
isPressed KEYWORD2
|
||||
keyStateChanged KEYWORD2
|
||||
numKeys KEYWORD2
|
||||
pin_mode KEYWORD2
|
||||
pin_write KEYWORD2
|
||||
pin_read KEYWORD2
|
||||
setDebounceTime KEYWORD2
|
||||
setHoldTime KEYWORD2
|
||||
waitForKey KEYWORD2
|
||||
|
||||
# this is a macro that converts 2d arrays to pointers
|
||||
makeKeymap KEYWORD2
|
||||
|
||||
# List of objects created in the example sketches.
|
||||
kpd KEYWORD3
|
||||
keypad KEYWORD3
|
||||
kbrd KEYWORD3
|
||||
keyboard KEYWORD3
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|| @file Key.cpp
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include "Key.hpp"
|
||||
|
||||
|
||||
// default constructor
|
||||
Key::Key() {
|
||||
kchar = NO_KEY;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
// constructor
|
||||
Key::Key(char userKeyChar) {
|
||||
kchar = userKeyChar;
|
||||
kcode = -1;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
|
||||
void Key::key_update (char userKeyChar, KeyState userState, boolean userStatus) {
|
||||
kchar = userKeyChar;
|
||||
kstate = userState;
|
||||
stateChanged = userStatus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
||
|
||||
|| @file Key.h
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEY_H
|
||||
#define KEY_H
|
||||
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define boolean bool
|
||||
#define byte unsigned char
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef enum{ IDLE, PRESSED, HOLD, RELEASED } KeyState;
|
||||
|
||||
const char NO_KEY = '\0';
|
||||
|
||||
class Key {
|
||||
public:
|
||||
// members
|
||||
char kchar;
|
||||
int kcode;
|
||||
KeyState kstate;
|
||||
boolean stateChanged;
|
||||
|
||||
// methods
|
||||
Key();
|
||||
Key(char userKeyChar);
|
||||
void key_update(char userKeyChar, KeyState userState, boolean userStatus);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
Binary file not shown.
@@ -0,0 +1,37 @@
|
||||
/* @file HelloKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates the simplest use of the matrix Keypad library.
|
||||
|| #
|
||||
*/
|
||||
#include "Keypad.hpp"
|
||||
#include <stdio.h>
|
||||
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] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
void setup(){
|
||||
//Serial.begin(9600);
|
||||
}
|
||||
|
||||
int main(){
|
||||
while(1){
|
||||
char key = keypad.getKey();
|
||||
|
||||
if (key){
|
||||
printf("%s \n",key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.cpp
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include "Keypad.hpp"
|
||||
|
||||
// <<constructor>> Allows custom keymap, pin configuration, and keypad sizes.
|
||||
Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols) {
|
||||
rowPins = row;
|
||||
columnPins = col;
|
||||
sizeKpd.rows = numRows;
|
||||
sizeKpd.columns = numCols;
|
||||
|
||||
begin(userKeymap);
|
||||
|
||||
setDebounceTime(10);
|
||||
setHoldTime(500);
|
||||
keypadEventListener = 0;
|
||||
|
||||
startTime = 0;
|
||||
single_key = false;
|
||||
}
|
||||
|
||||
// Let the user define a keymap - assume the same row/column count as defined in constructor
|
||||
void Keypad::begin(char *userKeymap) {
|
||||
keymap = userKeymap;
|
||||
}
|
||||
|
||||
// Returns a single key only. Retained for backwards compatibility.
|
||||
char Keypad::getKey() {
|
||||
single_key = true;
|
||||
|
||||
if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED))
|
||||
return key[0].kchar;
|
||||
|
||||
single_key = false;
|
||||
|
||||
return NO_KEY;
|
||||
}
|
||||
|
||||
// Populate the key list.
|
||||
bool Keypad::getKeys() {
|
||||
bool keyActivity = false;
|
||||
|
||||
// Limit how often the keypad is scanned. This makes the loop() run 10 times as fast.
|
||||
if ( (millis()-startTime)>debounceTime ) {
|
||||
scanKeys();
|
||||
keyActivity = updateList();
|
||||
startTime = millis();
|
||||
}
|
||||
|
||||
return keyActivity;
|
||||
}
|
||||
|
||||
// Private : Hardware scan
|
||||
void Keypad::scanKeys() {
|
||||
// Re-intialize the row pins. Allows sharing these pins with other hardware.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
pin_mode(rowPins[r],INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// bitMap stores ALL the keys that are being pressed.
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
pin_mode(columnPins[c],OUTPUT);
|
||||
pin_write(columnPins[c], LOW); // Begin column pulse output.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
bitWrite(bitMap[r], c, !pin_read(rowPins[r])); // keypress is active low so invert to high.
|
||||
}
|
||||
// Set pin to high impedance input. Effectively ends column pulse.
|
||||
pin_write(columnPins[c],HIGH);
|
||||
pin_mode(columnPins[c],INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
|
||||
bool Keypad::updateList() {
|
||||
|
||||
bool anyActivity = false;
|
||||
|
||||
// Delete any IDLE keys
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kstate==IDLE) {
|
||||
key[i].kchar = NO_KEY;
|
||||
key[i].kcode = -1;
|
||||
key[i].stateChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new keys to empty slots in the key list.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
boolean button = bitRead(bitMap[r],c);
|
||||
char keyChar = keymap[r * sizeKpd.columns + c];
|
||||
int keyCode = r * sizeKpd.columns + c;
|
||||
int idx = findInList (keyCode);
|
||||
// Key is already on the list so set its next state.
|
||||
if (idx > -1) {
|
||||
nextKeyState(idx, button);
|
||||
}
|
||||
// Key is NOT on the list so add it.
|
||||
if ((idx == -1) && button) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar==NO_KEY) { // Find an empty slot or don't add key to list.
|
||||
key[i].kchar = keyChar;
|
||||
key[i].kcode = keyCode;
|
||||
key[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
|
||||
nextKeyState (i, button);
|
||||
break; // Don't fill all the empty slots with the same key.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report if the user changed the state of any key.
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].stateChanged) anyActivity = true;
|
||||
}
|
||||
|
||||
return anyActivity;
|
||||
}
|
||||
|
||||
// Private
|
||||
// This function is a state machine but is also used for debouncing the keys.
|
||||
void Keypad::nextKeyState(byte idx, boolean button) {
|
||||
key[idx].stateChanged = false;
|
||||
|
||||
switch (key[idx].kstate) {
|
||||
case IDLE:
|
||||
if (button==CLOSED) {
|
||||
transitionTo (idx, PRESSED);
|
||||
holdTimer = millis(); } // Get ready for next HOLD state.
|
||||
break;
|
||||
case PRESSED:
|
||||
if ((millis()-holdTimer)>holdTime) // Waiting for a key HOLD...
|
||||
transitionTo (idx, HOLD);
|
||||
else if (button==OPEN) // or for a key to be RELEASED.
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case HOLD:
|
||||
if (button==OPEN)
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case RELEASED:
|
||||
transitionTo (idx, IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// New in 2.1
|
||||
bool Keypad::isPressed(char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if ( key[i].kchar == keyChar ) {
|
||||
if ( (key[i].kstate == PRESSED) && key[i].stateChanged )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Not pressed.
|
||||
}
|
||||
|
||||
// Search by character for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar == keyChar) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search by code for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (int keyCode) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kcode == keyCode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// New in 2.0
|
||||
char Keypad::waitForKey() {
|
||||
char waitKey = NO_KEY;
|
||||
while( (waitKey = getKey()) == NO_KEY ); // Block everything while waiting for a keypress.
|
||||
return waitKey;
|
||||
}
|
||||
|
||||
// Backwards compatibility function.
|
||||
KeyState Keypad::getState() {
|
||||
return key[0].kstate;
|
||||
}
|
||||
|
||||
// The end user can test for any changes in state before deciding
|
||||
// if any variables, etc. needs to be updated in their code.
|
||||
bool Keypad::keyStateChanged() {
|
||||
return key[0].stateChanged;
|
||||
}
|
||||
|
||||
// The number of keys on the key list, key[LIST_MAX], equals the number
|
||||
// of bytes in the key list divided by the number of bytes in a Key object.
|
||||
byte Keypad::numKeys() {
|
||||
return sizeof(key)/sizeof(Key);
|
||||
}
|
||||
|
||||
// Minimum debounceTime is 1 mS. Any lower *will* slow down the loop().
|
||||
void Keypad::setDebounceTime(uint debounce) {
|
||||
debounce<1 ? debounceTime=1 : debounceTime=debounce;
|
||||
}
|
||||
|
||||
void Keypad::setHoldTime(uint hold) {
|
||||
holdTime = hold;
|
||||
}
|
||||
|
||||
void Keypad::addEventListener(void (*listener)(char)){
|
||||
keypadEventListener = listener;
|
||||
}
|
||||
|
||||
void Keypad::transitionTo(byte idx, KeyState nextState) {
|
||||
key[idx].kstate = nextState;
|
||||
key[idx].stateChanged = true;
|
||||
|
||||
// Sketch used the getKey() function.
|
||||
// Calls keypadEventListener only when the first key in slot 0 changes state.
|
||||
if (single_key) {
|
||||
if ( (keypadEventListener!=NULL) && (idx==0) ) {
|
||||
keypadEventListener(key[0].kchar);
|
||||
}
|
||||
}
|
||||
// Sketch used the getKeys() function.
|
||||
// Calls keypadEventListener on any key that changes state.
|
||||
else {
|
||||
if (keypadEventListener!=NULL) {
|
||||
keypadEventListener(key[idx].kchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pin_mode(byte pinNum, byte mode) {
|
||||
if(mode == INPUT_PULLUP) {
|
||||
pinMode(pinNum, INPUT);
|
||||
pullUpDnControl(pinNum,PUD_UP);
|
||||
}
|
||||
else{
|
||||
pinMode(pinNum, mode);
|
||||
}
|
||||
}
|
||||
void pin_write(byte pinNum, boolean level) {
|
||||
digitalWrite(pinNum, level);
|
||||
}
|
||||
int pin_read(byte pinNum) {
|
||||
return digitalRead(pinNum);
|
||||
}
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added decision logic to compile WProgram.h or Arduino.h
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Every time a state changes the keypadEventListener will trigger, if set.
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime. setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.h
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEYPAD_H
|
||||
#define KEYPAD_H
|
||||
|
||||
#include "utility/Key.hpp"
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define NULL 0
|
||||
#define INPUT_PULLUP 0x02
|
||||
#define bitWrite(x,n,b) (b ? (x |= b<<n) : (x &= ~(b<<n)))
|
||||
#define bitRead(x,n) ((((x>>n)&1) == 1) ? 1 : 0)
|
||||
|
||||
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef char KeypadEvent;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
// Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0
|
||||
// by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :)
|
||||
typedef struct {
|
||||
byte rows;
|
||||
byte columns;
|
||||
} KeypadSize;
|
||||
|
||||
#define LIST_MAX 10 // Max number of keys on the active list.
|
||||
#define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns)
|
||||
#define makeKeymap(x) ((char*)x)
|
||||
|
||||
|
||||
//class Keypad : public Key, public HAL_obj {
|
||||
class Keypad : public Key {
|
||||
public:
|
||||
|
||||
Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
|
||||
|
||||
uint bitMap[MAPSIZE]; // 10 row x 16 column array of bits. Except Due which has 32 columns.
|
||||
Key key[LIST_MAX];
|
||||
unsigned long holdTimer;
|
||||
|
||||
char getKey();
|
||||
bool getKeys();
|
||||
KeyState getState();
|
||||
void begin(char *userKeymap);
|
||||
bool isPressed(char keyChar);
|
||||
void setDebounceTime(uint);
|
||||
void setHoldTime(uint);
|
||||
void addEventListener(void (*listener)(char));
|
||||
int findInList(char keyChar);
|
||||
int findInList(int keyCode);
|
||||
char waitForKey();
|
||||
bool keyStateChanged();
|
||||
byte numKeys();
|
||||
|
||||
private:
|
||||
unsigned long startTime;
|
||||
char *keymap;
|
||||
byte *rowPins;
|
||||
byte *columnPins;
|
||||
KeypadSize sizeKpd;
|
||||
uint debounceTime;
|
||||
uint holdTime;
|
||||
bool single_key;
|
||||
|
||||
void scanKeys();
|
||||
bool updateList();
|
||||
void nextKeyState(byte n, boolean button);
|
||||
void transitionTo(byte n, KeyState nextState);
|
||||
void (*keypadEventListener)(char);
|
||||
};
|
||||
|
||||
void pin_mode(byte pinNum, byte mode) ;
|
||||
|
||||
void pin_write(byte pinNum, boolean level) ;
|
||||
int pin_read(byte pinNum) ;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added test to determine which header file to compile,
|
||||
|| | WProgram.h or Arduino.h.
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes
|
||||
|| | the keypadEventListener will trigger, if set
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
Binary file not shown.
+37
@@ -0,0 +1,37 @@
|
||||
/* @file CustomKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates changing the keypad size and key values.
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 4; //four columns
|
||||
//define the cymbols on the buttons of the keypads
|
||||
char hexaKeys[ROWS][COLS] = {
|
||||
{'0','1','2','3'},
|
||||
{'4','5','6','7'},
|
||||
{'8','9','A','B'},
|
||||
{'C','D','E','F'}
|
||||
};
|
||||
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad
|
||||
|
||||
//initialize an instance of class NewKeypad
|
||||
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char customKey = customKeypad.getKey();
|
||||
|
||||
if (customKey){
|
||||
Serial.println(customKey);
|
||||
}
|
||||
}
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/* @file DynamicKeypad.pde
|
||||
|| @version 1.2
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| 07/11/12 - Re-modified (from DynamicKeypadJoe2) to use direct-connect kpds
|
||||
|| 02/28/12 - Modified to use I2C i/o G. D. (Joe) Young
|
||||
||
|
||||
||
|
||||
|| @dificulty: Intermediate
|
||||
||
|
||||
|| @description
|
||||
|| | This is a demonstration of keypadEvents. It's used to switch between keymaps
|
||||
|| | while using only one keypad. The main concepts being demonstrated are:
|
||||
|| |
|
||||
|| | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding.
|
||||
|| | How to use setHoldTime() and why.
|
||||
|| | Making more than one thing happen with the same key.
|
||||
|| | Assigning and changing keymaps on the fly.
|
||||
|| |
|
||||
|| | Another useful feature is also included with this demonstration although
|
||||
|| | it's not really one of the concepts that I wanted to show you. If you look
|
||||
|| | at the code in the PRESSED event you will see that the first section of that
|
||||
|| | code is used to scroll through three different letters on each key. For
|
||||
|| | example, pressing the '2' key will step through the letters 'd', 'e' and 'f'.
|
||||
|| |
|
||||
|| |
|
||||
|| | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding
|
||||
|| | Very simply, the PRESSED event occurs imediately upon detecting a pressed
|
||||
|| | key and will not happen again until after a RELEASED event. When the HOLD
|
||||
|| | event fires it always falls between PRESSED and RELEASED. However, it will
|
||||
|| | only occur if a key has been pressed for longer than the setHoldTime() interval.
|
||||
|| |
|
||||
|| | How to use setHoldTime() and why
|
||||
|| | Take a look at keypad.setHoldTime(500) in the code. It is used to set the
|
||||
|| | time delay between a PRESSED event and the start of a HOLD event. The value
|
||||
|| | 500 is in milliseconds (mS) and is equivalent to half a second. After pressing
|
||||
|| | a key for 500mS the HOLD event will fire and any code contained therein will be
|
||||
|| | executed. This event will stay active for as long as you hold the key except
|
||||
|| | in the case of bug #1 listed above.
|
||||
|| |
|
||||
|| | Making more than one thing happen with the same key.
|
||||
|| | If you look under the PRESSED event (case PRESSED:) you will see that the '#'
|
||||
|| | is used to print a new line, Serial.println(). But take a look at the first
|
||||
|| | half of the HOLD event and you will see the same key being used to switch back
|
||||
|| | and forth between the letter and number keymaps that were created with alphaKeys[4][5]
|
||||
|| | and numberKeys[4][5] respectively.
|
||||
|| |
|
||||
|| | Assigning and changing keymaps on the fly
|
||||
|| | You will see that the '#' key has been designated to perform two different functions
|
||||
|| | depending on how long you hold it down. If you press the '#' key for less than the
|
||||
|| | setHoldTime() then it will print a new line. However, if you hold if for longer
|
||||
|| | than that it will switch back and forth between numbers and letters. You can see the
|
||||
|| | keymap changes in the HOLD event.
|
||||
|| |
|
||||
|| |
|
||||
|| | In addition...
|
||||
|| | You might notice a couple of things that you won't find in the Arduino language
|
||||
|| | reference. The first would be #include <ctype.h>. This is a standard library from
|
||||
|| | the C programming language and though I don't normally demonstrate these types of
|
||||
|| | things from outside the Arduino language reference I felt that its use here was
|
||||
|| | justified by the simplicity that it brings to this sketch.
|
||||
|| | That simplicity is provided by the two calls to isalpha(key) and isdigit(key).
|
||||
|| | The first one is used to decide if the key that was pressed is any letter from a-z
|
||||
|| | or A-Z and the second one decides if the key is any number from 0-9. The return
|
||||
|| | value from these two functions is either a zero or some positive number greater
|
||||
|| | than zero. This makes it very simple to test a key and see if it is a number or
|
||||
|| | a letter. So when you see the following:
|
||||
|| |
|
||||
|| | if (isalpha(key)) // this tests to see if your key was a letter
|
||||
|| |
|
||||
|| | And the following may be more familiar to some but it is equivalent:
|
||||
|| |
|
||||
|| | if (isalpha(key) != 0) // this tests to see if your key was a letter
|
||||
|| |
|
||||
|| | And Finally...
|
||||
|| | To better understand how the event handler affects your code you will need to remember
|
||||
|| | that it gets called only when you press, hold or release a key. However, once a key
|
||||
|| | is pressed or held then the event handler gets called at the full speed of the loop().
|
||||
|| |
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
#include <ctype.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 3; //three columns
|
||||
// Define the keymaps. The blank spot (lower left) is the space character.
|
||||
char alphaKeys[ROWS][COLS] = {
|
||||
{ 'a','d','g' },
|
||||
{ 'j','m','p' },
|
||||
{ 's','v','y' },
|
||||
{ ' ','.','#' }
|
||||
};
|
||||
|
||||
char numberKeys[ROWS][COLS] = {
|
||||
{ '1','2','3' },
|
||||
{ '4','5','6' },
|
||||
{ '7','8','9' },
|
||||
{ ' ','0','#' }
|
||||
};
|
||||
|
||||
boolean alpha = false; // Start with the numeric keypad.
|
||||
|
||||
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
// Create two new keypads, one is a number pad and the other is a letter pad.
|
||||
Keypad numpad( makeKeymap(numberKeys), rowPins, colPins, sizeof(rowPins), sizeof(colPins) );
|
||||
Keypad ltrpad( makeKeymap(alphaKeys), rowPins, colPins, sizeof(rowPins), sizeof(colPins) );
|
||||
|
||||
|
||||
unsigned long startTime;
|
||||
const byte ledPin = 13; // Use the LED on pin 13.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
pinMode(ledPin, OUTPUT);
|
||||
digitalWrite(ledPin, LOW); // Turns the LED on.
|
||||
ltrpad.begin( makeKeymap(alphaKeys) );
|
||||
numpad.begin( makeKeymap(numberKeys) );
|
||||
ltrpad.addEventListener(keypadEvent_ltr); // Add an event listener.
|
||||
ltrpad.setHoldTime(500); // Default is 1000mS
|
||||
numpad.addEventListener(keypadEvent_num); // Add an event listener.
|
||||
numpad.setHoldTime(500); // Default is 1000mS
|
||||
}
|
||||
|
||||
char key;
|
||||
|
||||
void loop() {
|
||||
|
||||
if( alpha )
|
||||
key = ltrpad.getKey( );
|
||||
else
|
||||
key = numpad.getKey( );
|
||||
|
||||
if (alpha && millis()-startTime>100) { // Flash the LED if we are using the letter keymap.
|
||||
digitalWrite(ledPin,!digitalRead(ledPin));
|
||||
startTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
static char virtKey = NO_KEY; // Stores the last virtual key press. (Alpha keys only)
|
||||
static char physKey = NO_KEY; // Stores the last physical key press. (Alpha keys only)
|
||||
static char buildStr[12];
|
||||
static byte buildCount;
|
||||
static byte pressCount;
|
||||
|
||||
static byte kpadState;
|
||||
|
||||
// Take care of some special events.
|
||||
|
||||
void keypadEvent_ltr(KeypadEvent key) {
|
||||
// in here when in alpha mode.
|
||||
kpadState = ltrpad.getState( );
|
||||
swOnState( key );
|
||||
} // end ltrs keypad events
|
||||
|
||||
void keypadEvent_num( KeypadEvent key ) {
|
||||
// in here when using number keypad
|
||||
kpadState = numpad.getState( );
|
||||
swOnState( key );
|
||||
} // end numbers keypad events
|
||||
|
||||
void swOnState( char key ) {
|
||||
switch( kpadState ) {
|
||||
case PRESSED:
|
||||
if (isalpha(key)) { // This is a letter key so we're using the letter keymap.
|
||||
if (physKey != key) { // New key so start with the first of 3 characters.
|
||||
pressCount = 0;
|
||||
virtKey = key;
|
||||
physKey = key;
|
||||
}
|
||||
else { // Pressed the same key again...
|
||||
virtKey++; // so select the next character on that key.
|
||||
pressCount++; // Tracks how many times we press the same key.
|
||||
}
|
||||
if (pressCount > 2) { // Last character reached so cycle back to start.
|
||||
pressCount = 0;
|
||||
virtKey = key;
|
||||
}
|
||||
Serial.print(virtKey); // Used for testing.
|
||||
}
|
||||
if (isdigit(key) || key == ' ' || key == '.')
|
||||
Serial.print(key);
|
||||
if (key == '#')
|
||||
Serial.println();
|
||||
break;
|
||||
|
||||
case HOLD:
|
||||
if (key == '#') { // Toggle between keymaps.
|
||||
if (alpha == true) { // We are currently using a keymap with letters
|
||||
alpha = false; // Now we want a keymap with numbers.
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
else { // We are currently using a keymap with numbers
|
||||
alpha = true; // Now we want a keymap with letters.
|
||||
}
|
||||
}
|
||||
else { // Some key other than '#' was pressed.
|
||||
buildStr[buildCount++] = (isalpha(key)) ? virtKey : key;
|
||||
buildStr[buildCount] = '\0';
|
||||
Serial.println();
|
||||
Serial.println(buildStr);
|
||||
}
|
||||
break;
|
||||
|
||||
case RELEASED:
|
||||
if (buildCount >= sizeof(buildStr)) buildCount = 0; // Our string is full. Start fresh.
|
||||
break;
|
||||
} // end switch-case
|
||||
}// end switch on state function
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/* @file EventSerialKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates using the KeypadEvent.
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
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] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
byte ledPin = 13;
|
||||
|
||||
boolean blink = false;
|
||||
boolean ledPin_state;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
pinMode(ledPin, OUTPUT); // Sets the digital pin as output.
|
||||
digitalWrite(ledPin, HIGH); // Turn the LED on.
|
||||
ledPin_state = digitalRead(ledPin); // Store initial LED state. HIGH when LED is on.
|
||||
keypad.addEventListener(keypadEvent); // Add an event listener for this keypad
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char key = keypad.getKey();
|
||||
|
||||
if (key) {
|
||||
Serial.println(key);
|
||||
}
|
||||
if (blink){
|
||||
digitalWrite(ledPin,!digitalRead(ledPin)); // Change the ledPin from Hi2Lo or Lo2Hi.
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
// Taking care of some special events.
|
||||
void keypadEvent(KeypadEvent key){
|
||||
switch (keypad.getState()){
|
||||
case PRESSED:
|
||||
if (key == '#') {
|
||||
digitalWrite(ledPin,!digitalRead(ledPin));
|
||||
ledPin_state = digitalRead(ledPin); // Remember LED state, lit or unlit.
|
||||
}
|
||||
break;
|
||||
|
||||
case RELEASED:
|
||||
if (key == '*') {
|
||||
digitalWrite(ledPin,ledPin_state); // Restore LED state from before it started blinking.
|
||||
blink = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOLD:
|
||||
if (key == '*') {
|
||||
blink = true; // Blink the LED when holding the * key.
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/* @file HelloKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates the simplest use of the matrix Keypad library.
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
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] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char key = keypad.getKey();
|
||||
|
||||
if (key){
|
||||
Serial.println(key);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
#include <Keypad.h>
|
||||
|
||||
|
||||
const byte ROWS = 2; // use 4X4 keypad for both instances
|
||||
const byte COLS = 2;
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2'},
|
||||
{'3','4'}
|
||||
};
|
||||
byte rowPins[ROWS] = {5, 4}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {7, 6}; //connect to the column pinouts of the keypad
|
||||
Keypad kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
|
||||
const byte ROWSR = 2;
|
||||
const byte COLSR = 2;
|
||||
char keysR[ROWSR][COLSR] = {
|
||||
{'a','b'},
|
||||
{'c','d'}
|
||||
};
|
||||
byte rowPinsR[ROWSR] = {3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPinsR[COLSR] = {7, 6}; //connect to the column pinouts of the keypad
|
||||
Keypad kpdR( makeKeymap(keysR), rowPinsR, colPinsR, ROWSR, COLSR );
|
||||
|
||||
|
||||
const byte ROWSUR = 4;
|
||||
const byte COLSUR = 1;
|
||||
char keysUR[ROWSUR][COLSUR] = {
|
||||
{'M'},
|
||||
{'A'},
|
||||
{'R'},
|
||||
{'K'}
|
||||
};
|
||||
// Digitran keypad, bit numbers of PCF8574 i/o port
|
||||
byte rowPinsUR[ROWSUR] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPinsUR[COLSUR] = {8}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad kpdUR( makeKeymap(keysUR), rowPinsUR, colPinsUR, ROWSUR, COLSUR );
|
||||
|
||||
|
||||
void setup(){
|
||||
// Wire.begin( );
|
||||
kpdUR.begin( makeKeymap(keysUR) );
|
||||
kpdR.begin( makeKeymap(keysR) );
|
||||
kpd.begin( makeKeymap(keys) );
|
||||
Serial.begin(9600);
|
||||
Serial.println( "start" );
|
||||
}
|
||||
|
||||
//byte alternate = false;
|
||||
char key, keyR, keyUR;
|
||||
void loop(){
|
||||
|
||||
// alternate = !alternate;
|
||||
key = kpd.getKey( );
|
||||
keyUR = kpdUR.getKey( );
|
||||
keyR = kpdR.getKey( );
|
||||
|
||||
if (key){
|
||||
Serial.println(key);
|
||||
}
|
||||
if( keyR ) {
|
||||
Serial.println( keyR );
|
||||
}
|
||||
if( keyUR ) {
|
||||
Serial.println( keyUR );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/* @file MultiKey.ino
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | The latest version, 3.0, of the keypad library supports up to 10
|
||||
|| | active keys all being pressed at the same time. This sketch is an
|
||||
|| | example of how you can get multiple key presses from a keypad or
|
||||
|| | keyboard.
|
||||
|| #
|
||||
*/
|
||||
|
||||
#include <Keypad.h>
|
||||
|
||||
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] = {5, 4, 3, 2}; //connect to the row pinouts of the kpd
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the kpd
|
||||
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
unsigned long loopCount;
|
||||
unsigned long startTime;
|
||||
String msg;
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
loopCount = 0;
|
||||
startTime = millis();
|
||||
msg = "";
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
loopCount++;
|
||||
if ( (millis()-startTime)>5000 ) {
|
||||
Serial.print("Average loops per second = ");
|
||||
Serial.println(loopCount/5);
|
||||
startTime = millis();
|
||||
loopCount = 0;
|
||||
}
|
||||
|
||||
// Fills kpd.key[ ] array with up-to 10 active keys.
|
||||
// Returns true if there are ANY active keys.
|
||||
if (kpd.getKeys())
|
||||
{
|
||||
for (int i=0; i<LIST_MAX; i++) // Scan the whole key list.
|
||||
{
|
||||
if ( kpd.key[i].stateChanged ) // Only find keys that have changed state.
|
||||
{
|
||||
switch (kpd.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
|
||||
case PRESSED:
|
||||
msg = " PRESSED.";
|
||||
break;
|
||||
case HOLD:
|
||||
msg = " HOLD.";
|
||||
break;
|
||||
case RELEASED:
|
||||
msg = " RELEASED.";
|
||||
break;
|
||||
case IDLE:
|
||||
msg = " IDLE.";
|
||||
}
|
||||
Serial.print("Key ");
|
||||
Serial.print(kpd.key[i].kchar);
|
||||
Serial.println(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End loop
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#include <Keypad.h>
|
||||
|
||||
|
||||
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] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
unsigned long loopCount = 0;
|
||||
unsigned long timer_t = 0;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
|
||||
// Try playing with different debounceTime settings to see how it affects
|
||||
// the number of times per second your loop will run. The library prevents
|
||||
// setting it to anything below 1 millisecond.
|
||||
kpd.setDebounceTime(10); // setDebounceTime(mS)
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char key = kpd.getKey();
|
||||
|
||||
// Report the number of times through the loop in 1 second. This will give
|
||||
// you a relative idea of just how much the debounceTime has changed the
|
||||
// speed of your code. If you set a high debounceTime your loopCount will
|
||||
// look good but your keypresses will start to feel sluggish.
|
||||
if ((millis() - timer_t) > 1000) {
|
||||
Serial.print("Your loop code ran ");
|
||||
Serial.print(loopCount);
|
||||
Serial.println(" times over the last second");
|
||||
loopCount = 0;
|
||||
timer_t = millis();
|
||||
}
|
||||
loopCount++;
|
||||
if(key)
|
||||
Serial.println(key);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Keypad Library data types
|
||||
KeyState KEYWORD1
|
||||
Keypad KEYWORD1
|
||||
KeypadEvent KEYWORD1
|
||||
|
||||
# Keypad Library constants
|
||||
NO_KEY LITERAL1
|
||||
IDLE LITERAL1
|
||||
PRESSED LITERAL1
|
||||
HOLD LITERAL1
|
||||
RELEASED LITERAL1
|
||||
|
||||
# Keypad Library methods & functions
|
||||
addEventListener KEYWORD2
|
||||
bitMap KEYWORD2
|
||||
findKeyInList KEYWORD2
|
||||
getKey KEYWORD2
|
||||
getKeys KEYWORD2
|
||||
getState KEYWORD2
|
||||
holdTimer KEYWORD2
|
||||
isPressed KEYWORD2
|
||||
keyStateChanged KEYWORD2
|
||||
numKeys KEYWORD2
|
||||
pin_mode KEYWORD2
|
||||
pin_write KEYWORD2
|
||||
pin_read KEYWORD2
|
||||
setDebounceTime KEYWORD2
|
||||
setHoldTime KEYWORD2
|
||||
waitForKey KEYWORD2
|
||||
|
||||
# this is a macro that converts 2d arrays to pointers
|
||||
makeKeymap KEYWORD2
|
||||
|
||||
# List of objects created in the example sketches.
|
||||
kpd KEYWORD3
|
||||
keypad KEYWORD3
|
||||
kbrd KEYWORD3
|
||||
keyboard KEYWORD3
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|| @file Key.cpp
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include "Key.hpp"
|
||||
|
||||
|
||||
// default constructor
|
||||
Key::Key() {
|
||||
kchar = NO_KEY;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
// constructor
|
||||
Key::Key(char userKeyChar) {
|
||||
kchar = userKeyChar;
|
||||
kcode = -1;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
|
||||
void Key::key_update (char userKeyChar, KeyState userState, boolean userStatus) {
|
||||
kchar = userKeyChar;
|
||||
kstate = userState;
|
||||
stateChanged = userStatus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
||
|
||||
|| @file Key.h
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEY_H
|
||||
#define KEY_H
|
||||
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define boolean bool
|
||||
#define byte unsigned char
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef enum{ IDLE, PRESSED, HOLD, RELEASED } KeyState;
|
||||
|
||||
const char NO_KEY = '\0';
|
||||
|
||||
class Key {
|
||||
public:
|
||||
// members
|
||||
char kchar;
|
||||
int kcode;
|
||||
KeyState kstate;
|
||||
boolean stateChanged;
|
||||
|
||||
// methods
|
||||
Key();
|
||||
Key(char userKeyChar);
|
||||
void key_update(char userKeyChar, KeyState userState, boolean userStatus);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
#include <wiringPi.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
//#include "Keypad.hpp"
|
||||
#define bitWrite(x,n,b) (b ? (x |= 1<<n) : (x &= ~(1<<n)))
|
||||
#define bitRead(x,n) ((((x>>n)&1) == 1) ? 1 : 0)
|
||||
|
||||
int main(){
|
||||
unsigned char a=0x85,b=4,c=1;
|
||||
char ch = 'A';
|
||||
printf("a : %x\n",a);
|
||||
printf("%d,%d \n",bitRead(a,7),bitRead(a,4));
|
||||
|
||||
bitWrite(a,b,c);
|
||||
bitWrite(a,2,0);
|
||||
printf("a : %x\n",a);
|
||||
printf("%d,%d \n",bitRead(a,7),bitRead(a,4));
|
||||
|
||||
printf("char is %c ... \n",ch);
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**********************************************************************
|
||||
* Filename : MatrixKeypad.cpp
|
||||
* Description : obtain the key code of 4x4 Matrix Keypad
|
||||
* Author : freenove
|
||||
* modification: 2016/07/10
|
||||
**********************************************************************/
|
||||
#include "Keypad.hpp"
|
||||
#include <stdio.h>
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 4; //four columns
|
||||
char keys[ROWS][COLS] = { //key code
|
||||
{'1','2','3','A'},
|
||||
{'4','5','6','B'},
|
||||
{'7','8','9','C'},
|
||||
{'*','0','#','D'}
|
||||
};
|
||||
byte rowPins[ROWS] = {1, 4, 5, 6 }; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {12,3, 2, 0 }; //connect to the column pinouts of the keypad
|
||||
//create Keypad object
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
int main(){
|
||||
printf("Program is starting ... \n");
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
char key = 0;
|
||||
keypad.setDebounceTime(50);
|
||||
while(1){
|
||||
key = keypad.getKey(); //get the state of keys
|
||||
if (key){ //if a key is pressed, print out its key code
|
||||
printf("You Pressed key : %c \n",key);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,37 @@
|
||||
/**********************************************************************
|
||||
* Filename : SenseLED.c
|
||||
* Description : Controlling an led by infrared Motion sensor.
|
||||
* Author : freenove
|
||||
* modification: 2016/06/12
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 1 //define the ledPin
|
||||
#define sensorPin 0 //define the sensorPin
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(sensorPin, INPUT);
|
||||
|
||||
while(1){
|
||||
|
||||
if(digitalRead(sensorPin) == HIGH){ //sensor has pressed down
|
||||
digitalWrite(ledPin, HIGH); //led on
|
||||
printf("led on...\n");
|
||||
}
|
||||
else { //sensor has released
|
||||
digitalWrite(ledPin, LOW); //led off
|
||||
printf("...led off\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,69 @@
|
||||
/**********************************************************************
|
||||
* Filename : UltrasonicRanging.c
|
||||
* Description : Get distance from UltrasonicRanging
|
||||
* Author : freenove
|
||||
* modification: 2016/07/14
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define trigPin 4
|
||||
#define echoPin 5
|
||||
#define MAX_DISTANCE 220 // define the maximum measured distance
|
||||
#define timeOut MAX_DISTANCE*60 // calculate timeout according to the maximum measured distance
|
||||
//function pulseIn: obtain pulse time of a pin
|
||||
int pulseIn(int pin, int level, int timeout);
|
||||
float getSonar(){ // get the measurement results of ultrasonic module,with unit: cm
|
||||
long pingTime;
|
||||
float distance;
|
||||
digitalWrite(trigPin,HIGH); //trigPin send 10us high level
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(trigPin,LOW);
|
||||
pingTime = pulseIn(echoPin,HIGH,timeOut); //read plus time of echoPin
|
||||
distance = (float)pingTime * 340.0 / 2.0 / 10000.0; // the sound speed is 340m/s,and calculate distance
|
||||
return distance;
|
||||
}
|
||||
|
||||
int main(){
|
||||
printf("Program is starting ... \n");
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
float distance = 0;
|
||||
pinMode(trigPin,OUTPUT);
|
||||
pinMode(echoPin,INPUT);
|
||||
while(1){
|
||||
distance = getSonar();
|
||||
printf("The distance is : %.2f cm\n",distance);
|
||||
delay(1000);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pulseIn(int pin, int level, int timeout)
|
||||
{
|
||||
struct timeval tn, t0, t1;
|
||||
long micros;
|
||||
gettimeofday(&t0, NULL);
|
||||
micros = 0;
|
||||
while (digitalRead(pin) != level)
|
||||
{
|
||||
gettimeofday(&tn, NULL);
|
||||
if (tn.tv_sec > t0.tv_sec) micros = 1000000L; else micros = 0;
|
||||
micros += (tn.tv_usec - t0.tv_usec);
|
||||
if (micros > timeout) return 0;
|
||||
}
|
||||
gettimeofday(&t1, NULL);
|
||||
while (digitalRead(pin) == level)
|
||||
{
|
||||
gettimeofday(&tn, NULL);
|
||||
if (tn.tv_sec > t0.tv_sec) micros = 1000000L; else micros = 0;
|
||||
micros = micros + (tn.tv_usec - t0.tv_usec);
|
||||
if (micros > timeout) return 0;
|
||||
}
|
||||
if (tn.tv_sec > t1.tv_sec) micros = 1000000L; else micros = 0;
|
||||
micros = micros + (tn.tv_usec - t1.tv_usec);
|
||||
return micros;
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
// I2Cdev library collection - Main I2C device class
|
||||
// Abstracts bit and byte I2C R/W functions into a convenient class
|
||||
// 6/9/2012 by Jeff Rowberg <jeff@rowberg.net>
|
||||
//
|
||||
// Changelog:
|
||||
// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire
|
||||
// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation
|
||||
// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums)
|
||||
// 2011-10-03 - added automatic Arduino version detection for ease of use
|
||||
// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications
|
||||
// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x)
|
||||
// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default
|
||||
// 2011-08-02 - added support for 16-bit registers
|
||||
// - fixed incorrect Doxygen comments on some methods
|
||||
// - added timeout value for read operations (thanks mem @ Arduino forums)
|
||||
// 2011-07-30 - changed read/write function structures to return success or byte counts
|
||||
// - made all methods static for multi-device memory savings
|
||||
// 2011-07-28 - initial release
|
||||
|
||||
/* ============================================
|
||||
I2Cdev device library code is placed under the MIT license
|
||||
Copyright (c) 2012 Jeff Rowberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
===============================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include "I2Cdev.h"
|
||||
|
||||
/** Default constructor.
|
||||
*/
|
||||
I2Cdev::I2Cdev() {
|
||||
}
|
||||
|
||||
/** Read a single bit from an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to read from
|
||||
* @param bitNum Bit position to read (0-7)
|
||||
* @param data Container for single bit value
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) {
|
||||
uint8_t b;
|
||||
uint8_t count = readByte(devAddr, regAddr, &b, timeout);
|
||||
*data = b & (1 << bitNum);
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Read a single bit from a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to read from
|
||||
* @param bitNum Bit position to read (0-15)
|
||||
* @param data Container for single bit value
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) {
|
||||
uint16_t b;
|
||||
uint8_t count = readWord(devAddr, regAddr, &b, timeout);
|
||||
*data = b & (1 << bitNum);
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Read multiple bits from an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to read from
|
||||
* @param bitStart First bit position to read (0-7)
|
||||
* @param length Number of bits to read (not more than 8)
|
||||
* @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) {
|
||||
// 01101001 read byte
|
||||
// 76543210 bit numbers
|
||||
// xxx args: bitStart=4, length=3
|
||||
// 010 masked
|
||||
// -> 010 shifted
|
||||
uint8_t count, b;
|
||||
if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) {
|
||||
uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
b &= mask;
|
||||
b >>= (bitStart - length + 1);
|
||||
*data = b;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Read multiple bits from a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to read from
|
||||
* @param bitStart First bit position to read (0-15)
|
||||
* @param length Number of bits to read (not more than 16)
|
||||
* @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (1 = success, 0 = failure, -1 = timeout)
|
||||
*/
|
||||
int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) {
|
||||
// 1101011001101001 read byte
|
||||
// fedcba9876543210 bit numbers
|
||||
// xxx args: bitStart=12, length=3
|
||||
// 010 masked
|
||||
// -> 010 shifted
|
||||
uint8_t count;
|
||||
uint16_t w;
|
||||
if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) {
|
||||
uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
w &= mask;
|
||||
w >>= (bitStart - length + 1);
|
||||
*data = w;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Read single byte from an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to read from
|
||||
* @param data Container for byte value read from device
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) {
|
||||
return readBytes(devAddr, regAddr, 1, data, timeout);
|
||||
}
|
||||
|
||||
/** Read single word from a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to read from
|
||||
* @param data Container for word value read from device
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) {
|
||||
return readWords(devAddr, regAddr, 1, data, timeout);
|
||||
}
|
||||
|
||||
/** Read multiple bytes from an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr First register regAddr to read from
|
||||
* @param length Number of bytes to read
|
||||
* @param data Buffer to store read data in
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Number of bytes read (-1 indicates failure)
|
||||
*/
|
||||
int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) {
|
||||
int8_t count = 0;
|
||||
int fd = open("/dev/i2c-1", O_RDWR);
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Failed to open device: %s\n", strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
if (ioctl(fd, I2C_SLAVE, devAddr) < 0) {
|
||||
fprintf(stderr, "Failed to select device: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
if (write(fd, ®Addr, 1) != 1) {
|
||||
fprintf(stderr, "Failed to write reg: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
count = read(fd, data, length);
|
||||
if (count < 0) {
|
||||
fprintf(stderr, "Failed to read device(%d): %s\n", count, ::strerror(errno));
|
||||
close(fd);
|
||||
return(-1);
|
||||
} else if (count != length) {
|
||||
fprintf(stderr, "Short read from device, expected %d, got %d\n", length, count);
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Read multiple words from a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr First register regAddr to read from
|
||||
* @param length Number of words to read
|
||||
* @param data Buffer to store read data in
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Number of words read (0 indicates failure)
|
||||
*/
|
||||
int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) {
|
||||
int8_t count = 0;
|
||||
|
||||
printf("ReadWords() not implemented\n");
|
||||
// Use readBytes() and potential byteswap
|
||||
*data = 0; // keep the compiler quiet
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** write a single bit in an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to write to
|
||||
* @param bitNum Bit position to write (0-7)
|
||||
* @param value New bit value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) {
|
||||
uint8_t b;
|
||||
readByte(devAddr, regAddr, &b);
|
||||
b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
|
||||
return writeByte(devAddr, regAddr, b);
|
||||
}
|
||||
|
||||
/** write a single bit in a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to write to
|
||||
* @param bitNum Bit position to write (0-15)
|
||||
* @param value New bit value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) {
|
||||
uint16_t w;
|
||||
readWord(devAddr, regAddr, &w);
|
||||
w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum));
|
||||
return writeWord(devAddr, regAddr, w);
|
||||
}
|
||||
|
||||
/** Write multiple bits in an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to write to
|
||||
* @param bitStart First bit position to write (0-7)
|
||||
* @param length Number of bits to write (not more than 8)
|
||||
* @param data Right-aligned value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) {
|
||||
// 010 value to write
|
||||
// 76543210 bit numbers
|
||||
// xxx args: bitStart=4, length=3
|
||||
// 00011100 mask byte
|
||||
// 10101111 original value (sample)
|
||||
// 10100011 original & ~mask
|
||||
// 10101011 masked | value
|
||||
uint8_t b;
|
||||
if (readByte(devAddr, regAddr, &b) != 0) {
|
||||
uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
data <<= (bitStart - length + 1); // shift data into correct position
|
||||
data &= mask; // zero all non-important bits in data
|
||||
b &= ~(mask); // zero all important bits in existing byte
|
||||
b |= data; // combine data with existing byte
|
||||
return writeByte(devAddr, regAddr, b);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Write multiple bits in a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register regAddr to write to
|
||||
* @param bitStart First bit position to write (0-15)
|
||||
* @param length Number of bits to write (not more than 16)
|
||||
* @param data Right-aligned value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) {
|
||||
// 010 value to write
|
||||
// fedcba9876543210 bit numbers
|
||||
// xxx args: bitStart=12, length=3
|
||||
// 0001110000000000 mask byte
|
||||
// 1010111110010110 original value (sample)
|
||||
// 1010001110010110 original & ~mask
|
||||
// 1010101110010110 masked | value
|
||||
uint16_t w;
|
||||
if (readWord(devAddr, regAddr, &w) != 0) {
|
||||
uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
data <<= (bitStart - length + 1); // shift data into correct position
|
||||
data &= mask; // zero all non-important bits in data
|
||||
w &= ~(mask); // zero all important bits in existing word
|
||||
w |= data; // combine data with existing word
|
||||
return writeWord(devAddr, regAddr, w);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Write single byte to an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register address to write to
|
||||
* @param data New byte value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {
|
||||
return writeBytes(devAddr, regAddr, 1, &data);
|
||||
}
|
||||
|
||||
/** Write single word to a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr Register address to write to
|
||||
* @param data New word value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) {
|
||||
return writeWords(devAddr, regAddr, 1, &data);
|
||||
}
|
||||
|
||||
/** Write multiple bytes to an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr First register address to write to
|
||||
* @param length Number of bytes to write
|
||||
* @param data Buffer to copy new data from
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) {
|
||||
int8_t count = 0;
|
||||
uint8_t buf[128];
|
||||
int fd;
|
||||
|
||||
if (length > 127) {
|
||||
fprintf(stderr, "Byte write count (%d) > 127\n", length);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
fd = open("/dev/i2c-1", O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Failed to open device: %s\n", strerror(errno));
|
||||
return(FALSE);
|
||||
}
|
||||
if (ioctl(fd, I2C_SLAVE, devAddr) < 0) {
|
||||
fprintf(stderr, "Failed to select device: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return(FALSE);
|
||||
}
|
||||
buf[0] = regAddr;
|
||||
memcpy(buf+1,data,length);
|
||||
count = write(fd, buf, length+1);
|
||||
if (count < 0) {
|
||||
fprintf(stderr, "Failed to write device(%d): %s\n", count, ::strerror(errno));
|
||||
close(fd);
|
||||
return(FALSE);
|
||||
} else if (count != length+1) {
|
||||
fprintf(stderr, "Short write to device, expected %d, got %d\n", length+1, count);
|
||||
close(fd);
|
||||
return(FALSE);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Write multiple words to a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr First register address to write to
|
||||
* @param length Number of words to write
|
||||
* @param data Buffer to copy new data from
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) {
|
||||
int8_t count = 0;
|
||||
uint8_t buf[128];
|
||||
int i, fd;
|
||||
|
||||
// Should do potential byteswap and call writeBytes() really, but that
|
||||
// messes with the callers buffer
|
||||
|
||||
if (length > 63) {
|
||||
fprintf(stderr, "Word write count (%d) > 63\n", length);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
fd = open("/dev/i2c-1", O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Failed to open device: %s\n", strerror(errno));
|
||||
return(FALSE);
|
||||
}
|
||||
if (ioctl(fd, I2C_SLAVE, devAddr) < 0) {
|
||||
fprintf(stderr, "Failed to select device: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return(FALSE);
|
||||
}
|
||||
buf[0] = regAddr;
|
||||
for (i = 0; i < length; i++) {
|
||||
buf[i*2+1] = data[i] >> 8;
|
||||
buf[i*2+2] = data[i];
|
||||
}
|
||||
count = write(fd, buf, length*2+1);
|
||||
if (count < 0) {
|
||||
fprintf(stderr, "Failed to write device(%d): %s\n", count, ::strerror(errno));
|
||||
close(fd);
|
||||
return(FALSE);
|
||||
} else if (count != length*2+1) {
|
||||
fprintf(stderr, "Short write to device, expected %d, got %d\n", length+1, count);
|
||||
close(fd);
|
||||
return(FALSE);
|
||||
}
|
||||
close(fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Default timeout value for read operations.
|
||||
* Set this to 0 to disable timeout detection.
|
||||
*/
|
||||
uint16_t I2Cdev::readTimeout = 0;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// I2Cdev library collection - Main I2C device class header file
|
||||
// Abstracts bit and byte I2C R/W functions into a convenient class
|
||||
// 6/9/2012 by Jeff Rowberg <jeff@rowberg.net>
|
||||
//
|
||||
// Changelog:
|
||||
// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire
|
||||
// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation
|
||||
// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums)
|
||||
// 2011-10-03 - added automatic Arduino version detection for ease of use
|
||||
// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications
|
||||
// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x)
|
||||
// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default
|
||||
// 2011-08-02 - added support for 16-bit registers
|
||||
// - fixed incorrect Doxygen comments on some methods
|
||||
// - added timeout value for read operations (thanks mem @ Arduino forums)
|
||||
// 2011-07-30 - changed read/write function structures to return success or byte counts
|
||||
// - made all methods static for multi-device memory savings
|
||||
// 2011-07-28 - initial release
|
||||
|
||||
/* ============================================
|
||||
I2Cdev device library code is placed under the MIT license
|
||||
Copyright (c) 2012 Jeff Rowberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
===============================================
|
||||
*/
|
||||
|
||||
#ifndef _I2CDEV_H_
|
||||
#define _I2CDEV_H_
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1==1)
|
||||
#define FALSE (0==1)
|
||||
#endif
|
||||
|
||||
class I2Cdev {
|
||||
public:
|
||||
I2Cdev();
|
||||
|
||||
static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
|
||||
|
||||
static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data);
|
||||
static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data);
|
||||
static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data);
|
||||
static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data);
|
||||
static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data);
|
||||
static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data);
|
||||
static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data);
|
||||
static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data);
|
||||
|
||||
static uint16_t readTimeout;
|
||||
};
|
||||
|
||||
#endif /* _I2CDEV_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,988 @@
|
||||
// I2Cdev library collection - MPU6050 I2C device class
|
||||
// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00)
|
||||
// 10/3/2011 by Jeff Rowberg <jeff@rowberg.net>
|
||||
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
|
||||
//
|
||||
// Changelog:
|
||||
// ... - ongoing debug release
|
||||
|
||||
// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE
|
||||
// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF
|
||||
// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING.
|
||||
|
||||
/* ============================================
|
||||
I2Cdev device library code is placed under the MIT license
|
||||
Copyright (c) 2012 Jeff Rowberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
===============================================
|
||||
*/
|
||||
|
||||
#ifndef _MPU6050_H_
|
||||
#define _MPU6050_H_
|
||||
|
||||
#include "I2Cdev.h"
|
||||
//#include <avr/pgmspace.h>
|
||||
|
||||
#define pgm_read_byte(p) (*(uint8_t *)(p))
|
||||
|
||||
|
||||
#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
|
||||
#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC)
|
||||
#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW
|
||||
|
||||
#define MPU6050_RA_XG_OFFS_TC 0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
#define MPU6050_RA_YG_OFFS_TC 0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
#define MPU6050_RA_ZG_OFFS_TC 0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
#define MPU6050_RA_X_FINE_GAIN 0x03 //[7:0] X_FINE_GAIN
|
||||
#define MPU6050_RA_Y_FINE_GAIN 0x04 //[7:0] Y_FINE_GAIN
|
||||
#define MPU6050_RA_Z_FINE_GAIN 0x05 //[7:0] Z_FINE_GAIN
|
||||
#define MPU6050_RA_XA_OFFS_H 0x06 //[15:0] XA_OFFS
|
||||
#define MPU6050_RA_XA_OFFS_L_TC 0x07
|
||||
#define MPU6050_RA_YA_OFFS_H 0x08 //[15:0] YA_OFFS
|
||||
#define MPU6050_RA_YA_OFFS_L_TC 0x09
|
||||
#define MPU6050_RA_ZA_OFFS_H 0x0A //[15:0] ZA_OFFS
|
||||
#define MPU6050_RA_ZA_OFFS_L_TC 0x0B
|
||||
#define MPU6050_RA_XG_OFFS_USRH 0x13 //[15:0] XG_OFFS_USR
|
||||
#define MPU6050_RA_XG_OFFS_USRL 0x14
|
||||
#define MPU6050_RA_YG_OFFS_USRH 0x15 //[15:0] YG_OFFS_USR
|
||||
#define MPU6050_RA_YG_OFFS_USRL 0x16
|
||||
#define MPU6050_RA_ZG_OFFS_USRH 0x17 //[15:0] ZG_OFFS_USR
|
||||
#define MPU6050_RA_ZG_OFFS_USRL 0x18
|
||||
#define MPU6050_RA_SMPLRT_DIV 0x19
|
||||
#define MPU6050_RA_CONFIG 0x1A
|
||||
#define MPU6050_RA_GYRO_CONFIG 0x1B
|
||||
#define MPU6050_RA_ACCEL_CONFIG 0x1C
|
||||
#define MPU6050_RA_FF_THR 0x1D
|
||||
#define MPU6050_RA_FF_DUR 0x1E
|
||||
#define MPU6050_RA_MOT_THR 0x1F
|
||||
#define MPU6050_RA_MOT_DUR 0x20
|
||||
#define MPU6050_RA_ZRMOT_THR 0x21
|
||||
#define MPU6050_RA_ZRMOT_DUR 0x22
|
||||
#define MPU6050_RA_FIFO_EN 0x23
|
||||
#define MPU6050_RA_I2C_MST_CTRL 0x24
|
||||
#define MPU6050_RA_I2C_SLV0_ADDR 0x25
|
||||
#define MPU6050_RA_I2C_SLV0_REG 0x26
|
||||
#define MPU6050_RA_I2C_SLV0_CTRL 0x27
|
||||
#define MPU6050_RA_I2C_SLV1_ADDR 0x28
|
||||
#define MPU6050_RA_I2C_SLV1_REG 0x29
|
||||
#define MPU6050_RA_I2C_SLV1_CTRL 0x2A
|
||||
#define MPU6050_RA_I2C_SLV2_ADDR 0x2B
|
||||
#define MPU6050_RA_I2C_SLV2_REG 0x2C
|
||||
#define MPU6050_RA_I2C_SLV2_CTRL 0x2D
|
||||
#define MPU6050_RA_I2C_SLV3_ADDR 0x2E
|
||||
#define MPU6050_RA_I2C_SLV3_REG 0x2F
|
||||
#define MPU6050_RA_I2C_SLV3_CTRL 0x30
|
||||
#define MPU6050_RA_I2C_SLV4_ADDR 0x31
|
||||
#define MPU6050_RA_I2C_SLV4_REG 0x32
|
||||
#define MPU6050_RA_I2C_SLV4_DO 0x33
|
||||
#define MPU6050_RA_I2C_SLV4_CTRL 0x34
|
||||
#define MPU6050_RA_I2C_SLV4_DI 0x35
|
||||
#define MPU6050_RA_I2C_MST_STATUS 0x36
|
||||
#define MPU6050_RA_INT_PIN_CFG 0x37
|
||||
#define MPU6050_RA_INT_ENABLE 0x38
|
||||
#define MPU6050_RA_DMP_INT_STATUS 0x39
|
||||
#define MPU6050_RA_INT_STATUS 0x3A
|
||||
#define MPU6050_RA_ACCEL_XOUT_H 0x3B
|
||||
#define MPU6050_RA_ACCEL_XOUT_L 0x3C
|
||||
#define MPU6050_RA_ACCEL_YOUT_H 0x3D
|
||||
#define MPU6050_RA_ACCEL_YOUT_L 0x3E
|
||||
#define MPU6050_RA_ACCEL_ZOUT_H 0x3F
|
||||
#define MPU6050_RA_ACCEL_ZOUT_L 0x40
|
||||
#define MPU6050_RA_TEMP_OUT_H 0x41
|
||||
#define MPU6050_RA_TEMP_OUT_L 0x42
|
||||
#define MPU6050_RA_GYRO_XOUT_H 0x43
|
||||
#define MPU6050_RA_GYRO_XOUT_L 0x44
|
||||
#define MPU6050_RA_GYRO_YOUT_H 0x45
|
||||
#define MPU6050_RA_GYRO_YOUT_L 0x46
|
||||
#define MPU6050_RA_GYRO_ZOUT_H 0x47
|
||||
#define MPU6050_RA_GYRO_ZOUT_L 0x48
|
||||
#define MPU6050_RA_EXT_SENS_DATA_00 0x49
|
||||
#define MPU6050_RA_EXT_SENS_DATA_01 0x4A
|
||||
#define MPU6050_RA_EXT_SENS_DATA_02 0x4B
|
||||
#define MPU6050_RA_EXT_SENS_DATA_03 0x4C
|
||||
#define MPU6050_RA_EXT_SENS_DATA_04 0x4D
|
||||
#define MPU6050_RA_EXT_SENS_DATA_05 0x4E
|
||||
#define MPU6050_RA_EXT_SENS_DATA_06 0x4F
|
||||
#define MPU6050_RA_EXT_SENS_DATA_07 0x50
|
||||
#define MPU6050_RA_EXT_SENS_DATA_08 0x51
|
||||
#define MPU6050_RA_EXT_SENS_DATA_09 0x52
|
||||
#define MPU6050_RA_EXT_SENS_DATA_10 0x53
|
||||
#define MPU6050_RA_EXT_SENS_DATA_11 0x54
|
||||
#define MPU6050_RA_EXT_SENS_DATA_12 0x55
|
||||
#define MPU6050_RA_EXT_SENS_DATA_13 0x56
|
||||
#define MPU6050_RA_EXT_SENS_DATA_14 0x57
|
||||
#define MPU6050_RA_EXT_SENS_DATA_15 0x58
|
||||
#define MPU6050_RA_EXT_SENS_DATA_16 0x59
|
||||
#define MPU6050_RA_EXT_SENS_DATA_17 0x5A
|
||||
#define MPU6050_RA_EXT_SENS_DATA_18 0x5B
|
||||
#define MPU6050_RA_EXT_SENS_DATA_19 0x5C
|
||||
#define MPU6050_RA_EXT_SENS_DATA_20 0x5D
|
||||
#define MPU6050_RA_EXT_SENS_DATA_21 0x5E
|
||||
#define MPU6050_RA_EXT_SENS_DATA_22 0x5F
|
||||
#define MPU6050_RA_EXT_SENS_DATA_23 0x60
|
||||
#define MPU6050_RA_MOT_DETECT_STATUS 0x61
|
||||
#define MPU6050_RA_I2C_SLV0_DO 0x63
|
||||
#define MPU6050_RA_I2C_SLV1_DO 0x64
|
||||
#define MPU6050_RA_I2C_SLV2_DO 0x65
|
||||
#define MPU6050_RA_I2C_SLV3_DO 0x66
|
||||
#define MPU6050_RA_I2C_MST_DELAY_CTRL 0x67
|
||||
#define MPU6050_RA_SIGNAL_PATH_RESET 0x68
|
||||
#define MPU6050_RA_MOT_DETECT_CTRL 0x69
|
||||
#define MPU6050_RA_USER_CTRL 0x6A
|
||||
#define MPU6050_RA_PWR_MGMT_1 0x6B
|
||||
#define MPU6050_RA_PWR_MGMT_2 0x6C
|
||||
#define MPU6050_RA_BANK_SEL 0x6D
|
||||
#define MPU6050_RA_MEM_START_ADDR 0x6E
|
||||
#define MPU6050_RA_MEM_R_W 0x6F
|
||||
#define MPU6050_RA_DMP_CFG_1 0x70
|
||||
#define MPU6050_RA_DMP_CFG_2 0x71
|
||||
#define MPU6050_RA_FIFO_COUNTH 0x72
|
||||
#define MPU6050_RA_FIFO_COUNTL 0x73
|
||||
#define MPU6050_RA_FIFO_R_W 0x74
|
||||
#define MPU6050_RA_WHO_AM_I 0x75
|
||||
|
||||
#define MPU6050_TC_PWR_MODE_BIT 7
|
||||
#define MPU6050_TC_OFFSET_BIT 6
|
||||
#define MPU6050_TC_OFFSET_LENGTH 6
|
||||
#define MPU6050_TC_OTP_BNK_VLD_BIT 0
|
||||
|
||||
#define MPU6050_VDDIO_LEVEL_VLOGIC 0
|
||||
#define MPU6050_VDDIO_LEVEL_VDD 1
|
||||
|
||||
#define MPU6050_CFG_EXT_SYNC_SET_BIT 5
|
||||
#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3
|
||||
#define MPU6050_CFG_DLPF_CFG_BIT 2
|
||||
#define MPU6050_CFG_DLPF_CFG_LENGTH 3
|
||||
|
||||
#define MPU6050_EXT_SYNC_DISABLED 0x0
|
||||
#define MPU6050_EXT_SYNC_TEMP_OUT_L 0x1
|
||||
#define MPU6050_EXT_SYNC_GYRO_XOUT_L 0x2
|
||||
#define MPU6050_EXT_SYNC_GYRO_YOUT_L 0x3
|
||||
#define MPU6050_EXT_SYNC_GYRO_ZOUT_L 0x4
|
||||
#define MPU6050_EXT_SYNC_ACCEL_XOUT_L 0x5
|
||||
#define MPU6050_EXT_SYNC_ACCEL_YOUT_L 0x6
|
||||
#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L 0x7
|
||||
|
||||
#define MPU6050_DLPF_BW_256 0x00
|
||||
#define MPU6050_DLPF_BW_188 0x01
|
||||
#define MPU6050_DLPF_BW_98 0x02
|
||||
#define MPU6050_DLPF_BW_42 0x03
|
||||
#define MPU6050_DLPF_BW_20 0x04
|
||||
#define MPU6050_DLPF_BW_10 0x05
|
||||
#define MPU6050_DLPF_BW_5 0x06
|
||||
|
||||
#define MPU6050_GCONFIG_FS_SEL_BIT 4
|
||||
#define MPU6050_GCONFIG_FS_SEL_LENGTH 2
|
||||
|
||||
#define MPU6050_GYRO_FS_250 0x00
|
||||
#define MPU6050_GYRO_FS_500 0x01
|
||||
#define MPU6050_GYRO_FS_1000 0x02
|
||||
#define MPU6050_GYRO_FS_2000 0x03
|
||||
|
||||
#define MPU6050_ACONFIG_XA_ST_BIT 7
|
||||
#define MPU6050_ACONFIG_YA_ST_BIT 6
|
||||
#define MPU6050_ACONFIG_ZA_ST_BIT 5
|
||||
#define MPU6050_ACONFIG_AFS_SEL_BIT 4
|
||||
#define MPU6050_ACONFIG_AFS_SEL_LENGTH 2
|
||||
#define MPU6050_ACONFIG_ACCEL_HPF_BIT 2
|
||||
#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH 3
|
||||
|
||||
#define MPU6050_ACCEL_FS_2 0x00
|
||||
#define MPU6050_ACCEL_FS_4 0x01
|
||||
#define MPU6050_ACCEL_FS_8 0x02
|
||||
#define MPU6050_ACCEL_FS_16 0x03
|
||||
|
||||
#define MPU6050_DHPF_RESET 0x00
|
||||
#define MPU6050_DHPF_5 0x01
|
||||
#define MPU6050_DHPF_2P5 0x02
|
||||
#define MPU6050_DHPF_1P25 0x03
|
||||
#define MPU6050_DHPF_0P63 0x04
|
||||
#define MPU6050_DHPF_HOLD 0x07
|
||||
|
||||
#define MPU6050_TEMP_FIFO_EN_BIT 7
|
||||
#define MPU6050_XG_FIFO_EN_BIT 6
|
||||
#define MPU6050_YG_FIFO_EN_BIT 5
|
||||
#define MPU6050_ZG_FIFO_EN_BIT 4
|
||||
#define MPU6050_ACCEL_FIFO_EN_BIT 3
|
||||
#define MPU6050_SLV2_FIFO_EN_BIT 2
|
||||
#define MPU6050_SLV1_FIFO_EN_BIT 1
|
||||
#define MPU6050_SLV0_FIFO_EN_BIT 0
|
||||
|
||||
#define MPU6050_MULT_MST_EN_BIT 7
|
||||
#define MPU6050_WAIT_FOR_ES_BIT 6
|
||||
#define MPU6050_SLV_3_FIFO_EN_BIT 5
|
||||
#define MPU6050_I2C_MST_P_NSR_BIT 4
|
||||
#define MPU6050_I2C_MST_CLK_BIT 3
|
||||
#define MPU6050_I2C_MST_CLK_LENGTH 4
|
||||
|
||||
#define MPU6050_CLOCK_DIV_348 0x0
|
||||
#define MPU6050_CLOCK_DIV_333 0x1
|
||||
#define MPU6050_CLOCK_DIV_320 0x2
|
||||
#define MPU6050_CLOCK_DIV_308 0x3
|
||||
#define MPU6050_CLOCK_DIV_296 0x4
|
||||
#define MPU6050_CLOCK_DIV_286 0x5
|
||||
#define MPU6050_CLOCK_DIV_276 0x6
|
||||
#define MPU6050_CLOCK_DIV_267 0x7
|
||||
#define MPU6050_CLOCK_DIV_258 0x8
|
||||
#define MPU6050_CLOCK_DIV_500 0x9
|
||||
#define MPU6050_CLOCK_DIV_471 0xA
|
||||
#define MPU6050_CLOCK_DIV_444 0xB
|
||||
#define MPU6050_CLOCK_DIV_421 0xC
|
||||
#define MPU6050_CLOCK_DIV_400 0xD
|
||||
#define MPU6050_CLOCK_DIV_381 0xE
|
||||
#define MPU6050_CLOCK_DIV_364 0xF
|
||||
|
||||
#define MPU6050_I2C_SLV_RW_BIT 7
|
||||
#define MPU6050_I2C_SLV_ADDR_BIT 6
|
||||
#define MPU6050_I2C_SLV_ADDR_LENGTH 7
|
||||
#define MPU6050_I2C_SLV_EN_BIT 7
|
||||
#define MPU6050_I2C_SLV_BYTE_SW_BIT 6
|
||||
#define MPU6050_I2C_SLV_REG_DIS_BIT 5
|
||||
#define MPU6050_I2C_SLV_GRP_BIT 4
|
||||
#define MPU6050_I2C_SLV_LEN_BIT 3
|
||||
#define MPU6050_I2C_SLV_LEN_LENGTH 4
|
||||
|
||||
#define MPU6050_I2C_SLV4_RW_BIT 7
|
||||
#define MPU6050_I2C_SLV4_ADDR_BIT 6
|
||||
#define MPU6050_I2C_SLV4_ADDR_LENGTH 7
|
||||
#define MPU6050_I2C_SLV4_EN_BIT 7
|
||||
#define MPU6050_I2C_SLV4_INT_EN_BIT 6
|
||||
#define MPU6050_I2C_SLV4_REG_DIS_BIT 5
|
||||
#define MPU6050_I2C_SLV4_MST_DLY_BIT 4
|
||||
#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5
|
||||
|
||||
#define MPU6050_MST_PASS_THROUGH_BIT 7
|
||||
#define MPU6050_MST_I2C_SLV4_DONE_BIT 6
|
||||
#define MPU6050_MST_I2C_LOST_ARB_BIT 5
|
||||
#define MPU6050_MST_I2C_SLV4_NACK_BIT 4
|
||||
#define MPU6050_MST_I2C_SLV3_NACK_BIT 3
|
||||
#define MPU6050_MST_I2C_SLV2_NACK_BIT 2
|
||||
#define MPU6050_MST_I2C_SLV1_NACK_BIT 1
|
||||
#define MPU6050_MST_I2C_SLV0_NACK_BIT 0
|
||||
|
||||
#define MPU6050_INTCFG_INT_LEVEL_BIT 7
|
||||
#define MPU6050_INTCFG_INT_OPEN_BIT 6
|
||||
#define MPU6050_INTCFG_LATCH_INT_EN_BIT 5
|
||||
#define MPU6050_INTCFG_INT_RD_CLEAR_BIT 4
|
||||
#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT 3
|
||||
#define MPU6050_INTCFG_FSYNC_INT_EN_BIT 2
|
||||
#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT 1
|
||||
#define MPU6050_INTCFG_CLKOUT_EN_BIT 0
|
||||
|
||||
#define MPU6050_INTMODE_ACTIVEHIGH 0x00
|
||||
#define MPU6050_INTMODE_ACTIVELOW 0x01
|
||||
|
||||
#define MPU6050_INTDRV_PUSHPULL 0x00
|
||||
#define MPU6050_INTDRV_OPENDRAIN 0x01
|
||||
|
||||
#define MPU6050_INTLATCH_50USPULSE 0x00
|
||||
#define MPU6050_INTLATCH_WAITCLEAR 0x01
|
||||
|
||||
#define MPU6050_INTCLEAR_STATUSREAD 0x00
|
||||
#define MPU6050_INTCLEAR_ANYREAD 0x01
|
||||
|
||||
#define MPU6050_INTERRUPT_FF_BIT 7
|
||||
#define MPU6050_INTERRUPT_MOT_BIT 6
|
||||
#define MPU6050_INTERRUPT_ZMOT_BIT 5
|
||||
#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT 4
|
||||
#define MPU6050_INTERRUPT_I2C_MST_INT_BIT 3
|
||||
#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT 2
|
||||
#define MPU6050_INTERRUPT_DMP_INT_BIT 1
|
||||
#define MPU6050_INTERRUPT_DATA_RDY_BIT 0
|
||||
|
||||
// TODO: figure out what these actually do
|
||||
// UMPL source code is not very obivous
|
||||
#define MPU6050_DMPINT_5_BIT 5
|
||||
#define MPU6050_DMPINT_4_BIT 4
|
||||
#define MPU6050_DMPINT_3_BIT 3
|
||||
#define MPU6050_DMPINT_2_BIT 2
|
||||
#define MPU6050_DMPINT_1_BIT 1
|
||||
#define MPU6050_DMPINT_0_BIT 0
|
||||
|
||||
#define MPU6050_MOTION_MOT_XNEG_BIT 7
|
||||
#define MPU6050_MOTION_MOT_XPOS_BIT 6
|
||||
#define MPU6050_MOTION_MOT_YNEG_BIT 5
|
||||
#define MPU6050_MOTION_MOT_YPOS_BIT 4
|
||||
#define MPU6050_MOTION_MOT_ZNEG_BIT 3
|
||||
#define MPU6050_MOTION_MOT_ZPOS_BIT 2
|
||||
#define MPU6050_MOTION_MOT_ZRMOT_BIT 0
|
||||
|
||||
#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT 7
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT 4
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT 3
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT 2
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT 1
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT 0
|
||||
|
||||
#define MPU6050_PATHRESET_GYRO_RESET_BIT 2
|
||||
#define MPU6050_PATHRESET_ACCEL_RESET_BIT 1
|
||||
#define MPU6050_PATHRESET_TEMP_RESET_BIT 0
|
||||
|
||||
#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT 5
|
||||
#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH 2
|
||||
#define MPU6050_DETECT_FF_COUNT_BIT 3
|
||||
#define MPU6050_DETECT_FF_COUNT_LENGTH 2
|
||||
#define MPU6050_DETECT_MOT_COUNT_BIT 1
|
||||
#define MPU6050_DETECT_MOT_COUNT_LENGTH 2
|
||||
|
||||
#define MPU6050_DETECT_DECREMENT_RESET 0x0
|
||||
#define MPU6050_DETECT_DECREMENT_1 0x1
|
||||
#define MPU6050_DETECT_DECREMENT_2 0x2
|
||||
#define MPU6050_DETECT_DECREMENT_4 0x3
|
||||
|
||||
#define MPU6050_USERCTRL_DMP_EN_BIT 7
|
||||
#define MPU6050_USERCTRL_FIFO_EN_BIT 6
|
||||
#define MPU6050_USERCTRL_I2C_MST_EN_BIT 5
|
||||
#define MPU6050_USERCTRL_I2C_IF_DIS_BIT 4
|
||||
#define MPU6050_USERCTRL_DMP_RESET_BIT 3
|
||||
#define MPU6050_USERCTRL_FIFO_RESET_BIT 2
|
||||
#define MPU6050_USERCTRL_I2C_MST_RESET_BIT 1
|
||||
#define MPU6050_USERCTRL_SIG_COND_RESET_BIT 0
|
||||
|
||||
#define MPU6050_PWR1_DEVICE_RESET_BIT 7
|
||||
#define MPU6050_PWR1_SLEEP_BIT 6
|
||||
#define MPU6050_PWR1_CYCLE_BIT 5
|
||||
#define MPU6050_PWR1_TEMP_DIS_BIT 3
|
||||
#define MPU6050_PWR1_CLKSEL_BIT 2
|
||||
#define MPU6050_PWR1_CLKSEL_LENGTH 3
|
||||
|
||||
#define MPU6050_CLOCK_INTERNAL 0x00
|
||||
#define MPU6050_CLOCK_PLL_XGYRO 0x01
|
||||
#define MPU6050_CLOCK_PLL_YGYRO 0x02
|
||||
#define MPU6050_CLOCK_PLL_ZGYRO 0x03
|
||||
#define MPU6050_CLOCK_PLL_EXT32K 0x04
|
||||
#define MPU6050_CLOCK_PLL_EXT19M 0x05
|
||||
#define MPU6050_CLOCK_KEEP_RESET 0x07
|
||||
|
||||
#define MPU6050_PWR2_LP_WAKE_CTRL_BIT 7
|
||||
#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH 2
|
||||
#define MPU6050_PWR2_STBY_XA_BIT 5
|
||||
#define MPU6050_PWR2_STBY_YA_BIT 4
|
||||
#define MPU6050_PWR2_STBY_ZA_BIT 3
|
||||
#define MPU6050_PWR2_STBY_XG_BIT 2
|
||||
#define MPU6050_PWR2_STBY_YG_BIT 1
|
||||
#define MPU6050_PWR2_STBY_ZG_BIT 0
|
||||
|
||||
#define MPU6050_WAKE_FREQ_1P25 0x0
|
||||
#define MPU6050_WAKE_FREQ_2P5 0x1
|
||||
#define MPU6050_WAKE_FREQ_5 0x2
|
||||
#define MPU6050_WAKE_FREQ_10 0x3
|
||||
|
||||
#define MPU6050_BANKSEL_PRFTCH_EN_BIT 6
|
||||
#define MPU6050_BANKSEL_CFG_USER_BANK_BIT 5
|
||||
#define MPU6050_BANKSEL_MEM_SEL_BIT 4
|
||||
#define MPU6050_BANKSEL_MEM_SEL_LENGTH 5
|
||||
|
||||
#define MPU6050_WHO_AM_I_BIT 6
|
||||
#define MPU6050_WHO_AM_I_LENGTH 6
|
||||
|
||||
#define MPU6050_DMP_MEMORY_BANKS 8
|
||||
#define MPU6050_DMP_MEMORY_BANK_SIZE 256
|
||||
#define MPU6050_DMP_MEMORY_CHUNK_SIZE 16
|
||||
|
||||
// note: DMP code memory blocks defined at end of header file
|
||||
|
||||
class MPU6050 {
|
||||
public:
|
||||
MPU6050();
|
||||
MPU6050(uint8_t address);
|
||||
|
||||
void initialize();
|
||||
bool testConnection();
|
||||
|
||||
// AUX_VDDIO register
|
||||
uint8_t getAuxVDDIOLevel();
|
||||
void setAuxVDDIOLevel(uint8_t level);
|
||||
|
||||
// SMPLRT_DIV register
|
||||
uint8_t getRate();
|
||||
void setRate(uint8_t rate);
|
||||
|
||||
// CONFIG register
|
||||
uint8_t getExternalFrameSync();
|
||||
void setExternalFrameSync(uint8_t sync);
|
||||
uint8_t getDLPFMode();
|
||||
void setDLPFMode(uint8_t bandwidth);
|
||||
|
||||
// GYRO_CONFIG register
|
||||
uint8_t getFullScaleGyroRange();
|
||||
void setFullScaleGyroRange(uint8_t range);
|
||||
|
||||
// ACCEL_CONFIG register
|
||||
bool getAccelXSelfTest();
|
||||
void setAccelXSelfTest(bool enabled);
|
||||
bool getAccelYSelfTest();
|
||||
void setAccelYSelfTest(bool enabled);
|
||||
bool getAccelZSelfTest();
|
||||
void setAccelZSelfTest(bool enabled);
|
||||
uint8_t getFullScaleAccelRange();
|
||||
void setFullScaleAccelRange(uint8_t range);
|
||||
uint8_t getDHPFMode();
|
||||
void setDHPFMode(uint8_t mode);
|
||||
|
||||
// FF_THR register
|
||||
uint8_t getFreefallDetectionThreshold();
|
||||
void setFreefallDetectionThreshold(uint8_t threshold);
|
||||
|
||||
// FF_DUR register
|
||||
uint8_t getFreefallDetectionDuration();
|
||||
void setFreefallDetectionDuration(uint8_t duration);
|
||||
|
||||
// MOT_THR register
|
||||
uint8_t getMotionDetectionThreshold();
|
||||
void setMotionDetectionThreshold(uint8_t threshold);
|
||||
|
||||
// MOT_DUR register
|
||||
uint8_t getMotionDetectionDuration();
|
||||
void setMotionDetectionDuration(uint8_t duration);
|
||||
|
||||
// ZRMOT_THR register
|
||||
uint8_t getZeroMotionDetectionThreshold();
|
||||
void setZeroMotionDetectionThreshold(uint8_t threshold);
|
||||
|
||||
// ZRMOT_DUR register
|
||||
uint8_t getZeroMotionDetectionDuration();
|
||||
void setZeroMotionDetectionDuration(uint8_t duration);
|
||||
|
||||
// FIFO_EN register
|
||||
bool getTempFIFOEnabled();
|
||||
void setTempFIFOEnabled(bool enabled);
|
||||
bool getXGyroFIFOEnabled();
|
||||
void setXGyroFIFOEnabled(bool enabled);
|
||||
bool getYGyroFIFOEnabled();
|
||||
void setYGyroFIFOEnabled(bool enabled);
|
||||
bool getZGyroFIFOEnabled();
|
||||
void setZGyroFIFOEnabled(bool enabled);
|
||||
bool getAccelFIFOEnabled();
|
||||
void setAccelFIFOEnabled(bool enabled);
|
||||
bool getSlave2FIFOEnabled();
|
||||
void setSlave2FIFOEnabled(bool enabled);
|
||||
bool getSlave1FIFOEnabled();
|
||||
void setSlave1FIFOEnabled(bool enabled);
|
||||
bool getSlave0FIFOEnabled();
|
||||
void setSlave0FIFOEnabled(bool enabled);
|
||||
|
||||
// I2C_MST_CTRL register
|
||||
bool getMultiMasterEnabled();
|
||||
void setMultiMasterEnabled(bool enabled);
|
||||
bool getWaitForExternalSensorEnabled();
|
||||
void setWaitForExternalSensorEnabled(bool enabled);
|
||||
bool getSlave3FIFOEnabled();
|
||||
void setSlave3FIFOEnabled(bool enabled);
|
||||
bool getSlaveReadWriteTransitionEnabled();
|
||||
void setSlaveReadWriteTransitionEnabled(bool enabled);
|
||||
uint8_t getMasterClockSpeed();
|
||||
void setMasterClockSpeed(uint8_t speed);
|
||||
|
||||
// I2C_SLV* registers (Slave 0-3)
|
||||
uint8_t getSlaveAddress(uint8_t num);
|
||||
void setSlaveAddress(uint8_t num, uint8_t address);
|
||||
uint8_t getSlaveRegister(uint8_t num);
|
||||
void setSlaveRegister(uint8_t num, uint8_t reg);
|
||||
bool getSlaveEnabled(uint8_t num);
|
||||
void setSlaveEnabled(uint8_t num, bool enabled);
|
||||
bool getSlaveWordByteSwap(uint8_t num);
|
||||
void setSlaveWordByteSwap(uint8_t num, bool enabled);
|
||||
bool getSlaveWriteMode(uint8_t num);
|
||||
void setSlaveWriteMode(uint8_t num, bool mode);
|
||||
bool getSlaveWordGroupOffset(uint8_t num);
|
||||
void setSlaveWordGroupOffset(uint8_t num, bool enabled);
|
||||
uint8_t getSlaveDataLength(uint8_t num);
|
||||
void setSlaveDataLength(uint8_t num, uint8_t length);
|
||||
|
||||
// I2C_SLV* registers (Slave 4)
|
||||
uint8_t getSlave4Address();
|
||||
void setSlave4Address(uint8_t address);
|
||||
uint8_t getSlave4Register();
|
||||
void setSlave4Register(uint8_t reg);
|
||||
void setSlave4OutputByte(uint8_t data);
|
||||
bool getSlave4Enabled();
|
||||
void setSlave4Enabled(bool enabled);
|
||||
bool getSlave4InterruptEnabled();
|
||||
void setSlave4InterruptEnabled(bool enabled);
|
||||
bool getSlave4WriteMode();
|
||||
void setSlave4WriteMode(bool mode);
|
||||
uint8_t getSlave4MasterDelay();
|
||||
void setSlave4MasterDelay(uint8_t delay);
|
||||
uint8_t getSlate4InputByte();
|
||||
|
||||
// I2C_MST_STATUS register
|
||||
bool getPassthroughStatus();
|
||||
bool getSlave4IsDone();
|
||||
bool getLostArbitration();
|
||||
bool getSlave4Nack();
|
||||
bool getSlave3Nack();
|
||||
bool getSlave2Nack();
|
||||
bool getSlave1Nack();
|
||||
bool getSlave0Nack();
|
||||
|
||||
// INT_PIN_CFG register
|
||||
bool getInterruptMode();
|
||||
void setInterruptMode(bool mode);
|
||||
bool getInterruptDrive();
|
||||
void setInterruptDrive(bool drive);
|
||||
bool getInterruptLatch();
|
||||
void setInterruptLatch(bool latch);
|
||||
bool getInterruptLatchClear();
|
||||
void setInterruptLatchClear(bool clear);
|
||||
bool getFSyncInterruptLevel();
|
||||
void setFSyncInterruptLevel(bool level);
|
||||
bool getFSyncInterruptEnabled();
|
||||
void setFSyncInterruptEnabled(bool enabled);
|
||||
bool getI2CBypassEnabled();
|
||||
void setI2CBypassEnabled(bool enabled);
|
||||
bool getClockOutputEnabled();
|
||||
void setClockOutputEnabled(bool enabled);
|
||||
|
||||
// INT_ENABLE register
|
||||
uint8_t getIntEnabled();
|
||||
void setIntEnabled(uint8_t enabled);
|
||||
bool getIntFreefallEnabled();
|
||||
void setIntFreefallEnabled(bool enabled);
|
||||
bool getIntMotionEnabled();
|
||||
void setIntMotionEnabled(bool enabled);
|
||||
bool getIntZeroMotionEnabled();
|
||||
void setIntZeroMotionEnabled(bool enabled);
|
||||
bool getIntFIFOBufferOverflowEnabled();
|
||||
void setIntFIFOBufferOverflowEnabled(bool enabled);
|
||||
bool getIntI2CMasterEnabled();
|
||||
void setIntI2CMasterEnabled(bool enabled);
|
||||
bool getIntDataReadyEnabled();
|
||||
void setIntDataReadyEnabled(bool enabled);
|
||||
|
||||
// INT_STATUS register
|
||||
uint8_t getIntStatus();
|
||||
bool getIntFreefallStatus();
|
||||
bool getIntMotionStatus();
|
||||
bool getIntZeroMotionStatus();
|
||||
bool getIntFIFOBufferOverflowStatus();
|
||||
bool getIntI2CMasterStatus();
|
||||
bool getIntDataReadyStatus();
|
||||
|
||||
// ACCEL_*OUT_* registers
|
||||
void getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz);
|
||||
void getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
|
||||
void getAcceleration(int16_t* x, int16_t* y, int16_t* z);
|
||||
int16_t getAccelerationX();
|
||||
int16_t getAccelerationY();
|
||||
int16_t getAccelerationZ();
|
||||
|
||||
// TEMP_OUT_* registers
|
||||
int16_t getTemperature();
|
||||
|
||||
// GYRO_*OUT_* registers
|
||||
void getRotation(int16_t* x, int16_t* y, int16_t* z);
|
||||
int16_t getRotationX();
|
||||
int16_t getRotationY();
|
||||
int16_t getRotationZ();
|
||||
|
||||
// EXT_SENS_DATA_* registers
|
||||
uint8_t getExternalSensorByte(int position);
|
||||
uint16_t getExternalSensorWord(int position);
|
||||
uint32_t getExternalSensorDWord(int position);
|
||||
|
||||
// MOT_DETECT_STATUS register
|
||||
bool getXNegMotionDetected();
|
||||
bool getXPosMotionDetected();
|
||||
bool getYNegMotionDetected();
|
||||
bool getYPosMotionDetected();
|
||||
bool getZNegMotionDetected();
|
||||
bool getZPosMotionDetected();
|
||||
bool getZeroMotionDetected();
|
||||
|
||||
// I2C_SLV*_DO register
|
||||
void setSlaveOutputByte(uint8_t num, uint8_t data);
|
||||
|
||||
// I2C_MST_DELAY_CTRL register
|
||||
bool getExternalShadowDelayEnabled();
|
||||
void setExternalShadowDelayEnabled(bool enabled);
|
||||
bool getSlaveDelayEnabled(uint8_t num);
|
||||
void setSlaveDelayEnabled(uint8_t num, bool enabled);
|
||||
|
||||
// SIGNAL_PATH_RESET register
|
||||
void resetGyroscopePath();
|
||||
void resetAccelerometerPath();
|
||||
void resetTemperaturePath();
|
||||
|
||||
// MOT_DETECT_CTRL register
|
||||
uint8_t getAccelerometerPowerOnDelay();
|
||||
void setAccelerometerPowerOnDelay(uint8_t delay);
|
||||
uint8_t getFreefallDetectionCounterDecrement();
|
||||
void setFreefallDetectionCounterDecrement(uint8_t decrement);
|
||||
uint8_t getMotionDetectionCounterDecrement();
|
||||
void setMotionDetectionCounterDecrement(uint8_t decrement);
|
||||
|
||||
// USER_CTRL register
|
||||
bool getFIFOEnabled();
|
||||
void setFIFOEnabled(bool enabled);
|
||||
bool getI2CMasterModeEnabled();
|
||||
void setI2CMasterModeEnabled(bool enabled);
|
||||
void switchSPIEnabled(bool enabled);
|
||||
void resetFIFO();
|
||||
void resetI2CMaster();
|
||||
void resetSensors();
|
||||
|
||||
// PWR_MGMT_1 register
|
||||
void reset();
|
||||
bool getSleepEnabled();
|
||||
void setSleepEnabled(bool enabled);
|
||||
bool getWakeCycleEnabled();
|
||||
void setWakeCycleEnabled(bool enabled);
|
||||
bool getTempSensorEnabled();
|
||||
void setTempSensorEnabled(bool enabled);
|
||||
uint8_t getClockSource();
|
||||
void setClockSource(uint8_t source);
|
||||
|
||||
// PWR_MGMT_2 register
|
||||
uint8_t getWakeFrequency();
|
||||
void setWakeFrequency(uint8_t frequency);
|
||||
bool getStandbyXAccelEnabled();
|
||||
void setStandbyXAccelEnabled(bool enabled);
|
||||
bool getStandbyYAccelEnabled();
|
||||
void setStandbyYAccelEnabled(bool enabled);
|
||||
bool getStandbyZAccelEnabled();
|
||||
void setStandbyZAccelEnabled(bool enabled);
|
||||
bool getStandbyXGyroEnabled();
|
||||
void setStandbyXGyroEnabled(bool enabled);
|
||||
bool getStandbyYGyroEnabled();
|
||||
void setStandbyYGyroEnabled(bool enabled);
|
||||
bool getStandbyZGyroEnabled();
|
||||
void setStandbyZGyroEnabled(bool enabled);
|
||||
|
||||
// FIFO_COUNT_* registers
|
||||
uint16_t getFIFOCount();
|
||||
|
||||
// FIFO_R_W register
|
||||
uint8_t getFIFOByte();
|
||||
void setFIFOByte(uint8_t data);
|
||||
void getFIFOBytes(uint8_t *data, uint8_t length);
|
||||
|
||||
// WHO_AM_I register
|
||||
uint8_t getDeviceID();
|
||||
void setDeviceID(uint8_t id);
|
||||
|
||||
// ======== UNDOCUMENTED/DMP REGISTERS/METHODS ========
|
||||
|
||||
// XG_OFFS_TC register
|
||||
uint8_t getOTPBankValid();
|
||||
void setOTPBankValid(bool enabled);
|
||||
int8_t getXGyroOffset();
|
||||
void setXGyroOffset(int8_t offset);
|
||||
|
||||
// YG_OFFS_TC register
|
||||
int8_t getYGyroOffset();
|
||||
void setYGyroOffset(int8_t offset);
|
||||
|
||||
// ZG_OFFS_TC register
|
||||
int8_t getZGyroOffset();
|
||||
void setZGyroOffset(int8_t offset);
|
||||
|
||||
// X_FINE_GAIN register
|
||||
int8_t getXFineGain();
|
||||
void setXFineGain(int8_t gain);
|
||||
|
||||
// Y_FINE_GAIN register
|
||||
int8_t getYFineGain();
|
||||
void setYFineGain(int8_t gain);
|
||||
|
||||
// Z_FINE_GAIN register
|
||||
int8_t getZFineGain();
|
||||
void setZFineGain(int8_t gain);
|
||||
|
||||
// XA_OFFS_* registers
|
||||
int16_t getXAccelOffset();
|
||||
void setXAccelOffset(int16_t offset);
|
||||
|
||||
// YA_OFFS_* register
|
||||
int16_t getYAccelOffset();
|
||||
void setYAccelOffset(int16_t offset);
|
||||
|
||||
// ZA_OFFS_* register
|
||||
int16_t getZAccelOffset();
|
||||
void setZAccelOffset(int16_t offset);
|
||||
|
||||
// XG_OFFS_USR* registers
|
||||
int16_t getXGyroOffsetUser();
|
||||
void setXGyroOffsetUser(int16_t offset);
|
||||
|
||||
// YG_OFFS_USR* register
|
||||
int16_t getYGyroOffsetUser();
|
||||
void setYGyroOffsetUser(int16_t offset);
|
||||
|
||||
// ZG_OFFS_USR* register
|
||||
int16_t getZGyroOffsetUser();
|
||||
void setZGyroOffsetUser(int16_t offset);
|
||||
|
||||
// INT_ENABLE register (DMP functions)
|
||||
bool getIntPLLReadyEnabled();
|
||||
void setIntPLLReadyEnabled(bool enabled);
|
||||
bool getIntDMPEnabled();
|
||||
void setIntDMPEnabled(bool enabled);
|
||||
|
||||
// DMP_INT_STATUS
|
||||
bool getDMPInt5Status();
|
||||
bool getDMPInt4Status();
|
||||
bool getDMPInt3Status();
|
||||
bool getDMPInt2Status();
|
||||
bool getDMPInt1Status();
|
||||
bool getDMPInt0Status();
|
||||
|
||||
// INT_STATUS register (DMP functions)
|
||||
bool getIntPLLReadyStatus();
|
||||
bool getIntDMPStatus();
|
||||
|
||||
// USER_CTRL register (DMP functions)
|
||||
bool getDMPEnabled();
|
||||
void setDMPEnabled(bool enabled);
|
||||
void resetDMP();
|
||||
|
||||
// BANK_SEL register
|
||||
void setMemoryBank(uint8_t bank, bool prefetchEnabled=false, bool userBank=false);
|
||||
|
||||
// MEM_START_ADDR register
|
||||
void setMemoryStartAddress(uint8_t address);
|
||||
|
||||
// MEM_R_W register
|
||||
uint8_t readMemoryByte();
|
||||
void writeMemoryByte(uint8_t data);
|
||||
void readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0);
|
||||
bool writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0, bool verify=true, bool useProgMem=false);
|
||||
bool writeProgMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0, bool verify=true);
|
||||
|
||||
bool writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, bool useProgMem=false);
|
||||
bool writeProgDMPConfigurationSet(const uint8_t *data, uint16_t dataSize);
|
||||
|
||||
// DMP_CFG_1 register
|
||||
uint8_t getDMPConfig1();
|
||||
void setDMPConfig1(uint8_t config);
|
||||
|
||||
// DMP_CFG_2 register
|
||||
uint8_t getDMPConfig2();
|
||||
void setDMPConfig2(uint8_t config);
|
||||
|
||||
// special methods for MotionApps 2.0 implementation
|
||||
#ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS20
|
||||
uint8_t *dmpPacketBuffer;
|
||||
uint16_t dmpPacketSize;
|
||||
|
||||
uint8_t dmpInitialize();
|
||||
bool dmpPacketAvailable();
|
||||
|
||||
uint8_t dmpSetFIFORate(uint8_t fifoRate);
|
||||
uint8_t dmpGetFIFORate();
|
||||
uint8_t dmpGetSampleStepSizeMS();
|
||||
uint8_t dmpGetSampleFrequency();
|
||||
int32_t dmpDecodeTemperature(int8_t tempReg);
|
||||
|
||||
// Register callbacks after a packet of FIFO data is processed
|
||||
//uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority);
|
||||
//uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func);
|
||||
uint8_t dmpRunFIFORateProcesses();
|
||||
|
||||
// Setup FIFO for various output
|
||||
uint8_t dmpSendQuaternion(uint_fast16_t accuracy);
|
||||
uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendPacketNumber(uint_fast16_t accuracy);
|
||||
uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
|
||||
// Get Fixed Point data from FIFO
|
||||
uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0);
|
||||
uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0);
|
||||
uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpSetLinearAccelFilterCoefficient(float coef);
|
||||
uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity);
|
||||
uint8_t dmpGetLinearAccelInWorld(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccelInWorld(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q);
|
||||
uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q);
|
||||
uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0);
|
||||
uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0);
|
||||
|
||||
uint8_t dmpGetEuler(float *data, Quaternion *q);
|
||||
uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity);
|
||||
|
||||
// Get Floating Point data from FIFO
|
||||
uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0);
|
||||
|
||||
uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData);
|
||||
uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL);
|
||||
|
||||
uint8_t dmpSetFIFOProcessedCallback(void (*func) (void));
|
||||
|
||||
uint8_t dmpInitFIFOParam();
|
||||
uint8_t dmpCloseFIFO();
|
||||
uint8_t dmpSetGyroDataSource(uint8_t source);
|
||||
uint8_t dmpDecodeQuantizedAccel();
|
||||
uint32_t dmpGetGyroSumOfSquare();
|
||||
uint32_t dmpGetAccelSumOfSquare();
|
||||
void dmpOverrideQuaternion(long *q);
|
||||
uint16_t dmpGetFIFOPacketSize();
|
||||
#endif
|
||||
|
||||
// special methods for MotionApps 4.1 implementation
|
||||
#ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS41
|
||||
uint8_t *dmpPacketBuffer;
|
||||
uint16_t dmpPacketSize;
|
||||
|
||||
uint8_t dmpInitialize();
|
||||
bool dmpPacketAvailable();
|
||||
|
||||
uint8_t dmpSetFIFORate(uint8_t fifoRate);
|
||||
uint8_t dmpGetFIFORate();
|
||||
uint8_t dmpGetSampleStepSizeMS();
|
||||
uint8_t dmpGetSampleFrequency();
|
||||
int32_t dmpDecodeTemperature(int8_t tempReg);
|
||||
|
||||
// Register callbacks after a packet of FIFO data is processed
|
||||
//uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority);
|
||||
//uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func);
|
||||
uint8_t dmpRunFIFORateProcesses();
|
||||
|
||||
// Setup FIFO for various output
|
||||
uint8_t dmpSendQuaternion(uint_fast16_t accuracy);
|
||||
uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendPacketNumber(uint_fast16_t accuracy);
|
||||
uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy);
|
||||
|
||||
// Get Fixed Point data from FIFO
|
||||
uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0);
|
||||
uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0);
|
||||
uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetMag(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpSetLinearAccelFilterCoefficient(float coef);
|
||||
uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity);
|
||||
uint8_t dmpGetLinearAccelInWorld(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccelInWorld(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q);
|
||||
uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q);
|
||||
uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0);
|
||||
uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0);
|
||||
uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0);
|
||||
|
||||
uint8_t dmpGetEuler(float *data, Quaternion *q);
|
||||
uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity);
|
||||
|
||||
// Get Floating Point data from FIFO
|
||||
uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0);
|
||||
uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0);
|
||||
|
||||
uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData);
|
||||
uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL);
|
||||
|
||||
uint8_t dmpSetFIFOProcessedCallback(void (*func) (void));
|
||||
|
||||
uint8_t dmpInitFIFOParam();
|
||||
uint8_t dmpCloseFIFO();
|
||||
uint8_t dmpSetGyroDataSource(uint8_t source);
|
||||
uint8_t dmpDecodeQuantizedAccel();
|
||||
uint32_t dmpGetGyroSumOfSquare();
|
||||
uint32_t dmpGetAccelSumOfSquare();
|
||||
void dmpOverrideQuaternion(long *q);
|
||||
uint16_t dmpGetFIFOPacketSize();
|
||||
#endif
|
||||
|
||||
private:
|
||||
uint8_t devAddr;
|
||||
uint8_t buffer[14];
|
||||
};
|
||||
|
||||
#endif /* _MPU6050_H_ */
|
||||
@@ -0,0 +1,45 @@
|
||||
/**********************************************************************
|
||||
* Filename : MPU6050RAW.c
|
||||
* Description : Read the Raw data of MPU6050
|
||||
* Author : freenove
|
||||
* modification: 2016/07/18
|
||||
**********************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include "I2Cdev.h"
|
||||
#include "MPU6050.h"
|
||||
|
||||
MPU6050 accelgyro; //instantiate a MPU6050 class object
|
||||
|
||||
int16_t ax, ay, az; //store acceleration data
|
||||
int16_t gx, gy, gz; //store gyroscope data
|
||||
|
||||
void setup() {
|
||||
// initialize device
|
||||
printf("Initializing I2C devices...\n");
|
||||
accelgyro.initialize(); //initialize MPU6050
|
||||
|
||||
// verify connection
|
||||
printf("Testing device connections...\n");
|
||||
printf(accelgyro.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// read raw accel/gyro measurements from device
|
||||
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
|
||||
// display accel/gyro x/y/z values
|
||||
printf("a/g: %6hd %6hd %6hd %6hd %6hd %6hd\n",ax,ay,az,gx,gy,gz);
|
||||
printf("a/g: %.2f g %.2f g %.2f g %.2f d/s %.2f d/s %.2f d/s \n",(float)ax/16384,(float)ay/16384,(float)az/16384,
|
||||
(float)gx/131,(float)gy/131,(float)gz/131);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
setup();
|
||||
while(1){
|
||||
loop();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,54 @@
|
||||
/**********************************************************************
|
||||
* Filename : LightWater03.c
|
||||
* Description : Control LED by 74HC595 on the DIY circuit board
|
||||
* Author : freenove
|
||||
* modification: 2016/08/16
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringShift.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define dataPin 0 //DS Pin of 74HC595(Pin14)
|
||||
#define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
|
||||
#define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
|
||||
//Define an array to save the pulse width of LED. Output the signal to the 8 adjacent LEDs in order.
|
||||
const int pluseWidth[]={0,0,0,0,0,0,0,0,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0};
|
||||
void outData(int8_t data){
|
||||
digitalWrite(latchPin,LOW);
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,data);
|
||||
digitalWrite(latchPin,HIGH);
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int i,j,index; //index:current position in array pluseWidth
|
||||
int moveSpeed = 100; //move speed delay, the larger, the slower
|
||||
long lastMove; //Record the last time point of the move
|
||||
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
|
||||
printf("setup wiringPi failed !");
|
||||
return 1;
|
||||
}
|
||||
pinMode(dataPin,OUTPUT);
|
||||
pinMode(latchPin,OUTPUT);
|
||||
pinMode(clockPin,OUTPUT);
|
||||
index = 0; //Starting from the array index 0
|
||||
lastMove = millis(); //the start time
|
||||
while(1){
|
||||
if(millis() - lastMove > moveSpeed) { //speed control
|
||||
lastMove = millis(); //Record the time point of the move
|
||||
index++; //move to next
|
||||
if(index > 15) index = 0; //index to 0
|
||||
}
|
||||
for(i=0;i<64;i++){ //The cycle of PWM is 64 cycles
|
||||
int8_t data = 0; //This loop of output data
|
||||
for(j=0;j<8;j++){ //Calculate the output state of this loop
|
||||
if(i < pluseWidth[index+j]){ //Calculate the LED state according to the pulse width
|
||||
data |= 0x01<<j ; //Calculate the data
|
||||
}
|
||||
}
|
||||
outData(data); //Send the data to 74HC595
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : Blink.py
|
||||
# Description : Make an led blinking.
|
||||
# auther : www.freenove.com
|
||||
# modification: 2016/06/07
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
ledPin = 11 # RPI Board pin11
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
|
||||
GPIO.output(ledPin, GPIO.LOW) # Set ledPin low to off led
|
||||
print 'using pin%d'%ledPin
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
GPIO.output(ledPin, GPIO.HIGH) # led on
|
||||
print '...led on'
|
||||
time.sleep(1)
|
||||
GPIO.output(ledPin, GPIO.LOW) # led off
|
||||
print 'led off...'
|
||||
time.sleep(1)
|
||||
|
||||
def destroy():
|
||||
GPIO.output(ledPin, GPIO.LOW) # led off
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : ButtonLED.py
|
||||
# Description : Controlling an led by button.
|
||||
# Author : freenove
|
||||
# modification: 2016/06/12
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
ledPin = 11 # define the ledPin
|
||||
buttonPin = 12 # define the buttonPin
|
||||
|
||||
def setup():
|
||||
print 'Program is starting...'
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is input, and pull up to high level(3.3V)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
if GPIO.input(buttonPin)==GPIO.LOW:
|
||||
GPIO.output(ledPin,GPIO.HIGH)
|
||||
print 'led on ...'
|
||||
else :
|
||||
GPIO.output(ledPin,GPIO.LOW)
|
||||
print 'led off ...'
|
||||
|
||||
def destroy():
|
||||
GPIO.output(ledPin, GPIO.LOW) # led off
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : Tablelamp.py
|
||||
# Description : a DIY MINI table lamp
|
||||
# Author : freenove
|
||||
# modification: 2016/06/12
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
ledPin = 11 # define the ledPin
|
||||
buttonPin = 12 # define the buttonPin
|
||||
ledState = False
|
||||
|
||||
def setup():
|
||||
print 'Program is starting...'
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is input, and pull up to high
|
||||
|
||||
def buttonEvent(channel):#When the button is pressed, this function will be executed
|
||||
global ledState
|
||||
print 'buttonEvent GPIO%d'%channel
|
||||
ledState = not ledState
|
||||
if ledState :
|
||||
print 'Turn on LED ... '
|
||||
else :
|
||||
print 'Turn off LED ... '
|
||||
GPIO.output(ledPin,ledState)
|
||||
|
||||
def loop():
|
||||
#Button detect
|
||||
GPIO.add_event_detect(buttonPin,GPIO.FALLING,callback = buttonEvent,bouncetime=300)
|
||||
while True:
|
||||
pass
|
||||
|
||||
def destroy():
|
||||
GPIO.output(ledPin, GPIO.LOW) # led off
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : LightWater.py
|
||||
# Description : Display 10 LEDBar Graph
|
||||
# Author : freenove
|
||||
# modification: 2016/06/13
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
ledPins = [11, 12, 13, 15, 16, 18, 22, 3, 5, 24]
|
||||
|
||||
def setup():
|
||||
print 'Program is starting...'
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
for pin in ledPins:
|
||||
GPIO.setup(pin, GPIO.OUT) # Set all ledPins' mode is output
|
||||
GPIO.output(pin, GPIO.HIGH) # Set all ledPins to high(+3.3V) to off led
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for pin in ledPins: #make led on from left to right
|
||||
GPIO.output(pin, GPIO.LOW)
|
||||
time.sleep(0.1)
|
||||
GPIO.output(pin, GPIO.HIGH)
|
||||
for pin in ledPins[10:0:-1]: #make led on from right to left
|
||||
GPIO.output(pin, GPIO.LOW)
|
||||
time.sleep(0.1)
|
||||
GPIO.output(pin, GPIO.HIGH)
|
||||
|
||||
def destroy():
|
||||
for pin in ledPins:
|
||||
GPIO.output(pin, GPIO.HIGH) # turn off all leds
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : BreathingLED.py
|
||||
# Description : A breathing LED
|
||||
# Author : freenove
|
||||
# modification: 2016/06/14
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
LedPin = 12
|
||||
|
||||
def setup():
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
GPIO.setup(LedPin, GPIO.OUT) # Set LedPin's mode is output
|
||||
GPIO.output(LedPin, GPIO.LOW) # Set LedPin to low
|
||||
|
||||
p = GPIO.PWM(LedPin, 1000) # set Frequece to 1KHz
|
||||
p.start(0) # Duty Cycle = 0
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for dc in range(0, 101, 1): # Increase duty cycle: 0~100
|
||||
p.ChangeDutyCycle(dc) # Change duty cycle
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
for dc in range(100, -1, -1): # Decrease duty cycle: 100~0
|
||||
p.ChangeDutyCycle(dc)
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
|
||||
def destroy():
|
||||
p.stop()
|
||||
GPIO.output(LedPin, GPIO.LOW) # turn off led
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : ColorfulLED.py
|
||||
# Description : A auto flash ColorfulLED
|
||||
# Author : freenove
|
||||
# modification: 2016/06/15
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import random
|
||||
|
||||
pins = {'pin_R':11, 'pin_G':12, 'pin_B':13} # pins is a dict
|
||||
|
||||
def setup():
|
||||
global p_R,p_G,p_B
|
||||
print 'Program is starting ... '
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
for i in pins:
|
||||
GPIO.setup(pins[i], GPIO.OUT) # Set pins' mode is output
|
||||
GPIO.output(pins[i], GPIO.HIGH) # Set pins to high(+3.3V) to off led
|
||||
p_R = GPIO.PWM(pins['pin_R'], 2000) # set Frequece to 2KHz
|
||||
p_G = GPIO.PWM(pins['pin_G'], 2000)
|
||||
p_B = GPIO.PWM(pins['pin_B'], 2000)
|
||||
p_R.start(0) # Initial duty Cycle = 0
|
||||
p_G.start(0)
|
||||
p_B.start(0)
|
||||
|
||||
def setColor(r_val,g_val,b_val):
|
||||
p_R.ChangeDutyCycle(r_val) # Change duty cycle
|
||||
p_G.ChangeDutyCycle(g_val)
|
||||
p_B.ChangeDutyCycle(b_val)
|
||||
|
||||
def loop():
|
||||
while True :
|
||||
r=random.randint(0,100)#get a random in (0,100)
|
||||
g=random.randint(0,100)
|
||||
b=random.randint(0,100)
|
||||
setColor(r,g,b)#set random as a duty cycle value
|
||||
print 'r=%d, g=%d, b=%d '%(r ,g, b)
|
||||
time.sleep(0.3)
|
||||
|
||||
def destroy():
|
||||
p_R.stop()
|
||||
p_G.stop()
|
||||
p_B.stop()
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : Doorbell.py
|
||||
# Description : Controlling an buzzer by button.
|
||||
# Author : freenove
|
||||
# modification: 2016/06/12
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
buzzerPin = 11 # define the buzzerPin
|
||||
buttonPin = 12 # define the buttonPin
|
||||
|
||||
def setup():
|
||||
print 'Program is starting...'
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
GPIO.setup(buzzerPin, GPIO.OUT) # Set buzzerPin's mode is output
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is input, and pull up to high level(3.3V)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
if GPIO.input(buttonPin)==GPIO.LOW:
|
||||
GPIO.output(buzzerPin,GPIO.HIGH)
|
||||
print 'buzzer on ...'
|
||||
else :
|
||||
GPIO.output(buzzerPin,GPIO.LOW)
|
||||
print 'buzzer off ...'
|
||||
|
||||
def destroy():
|
||||
GPIO.output(buzzerPin, GPIO.LOW) # buzzer off
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
########################################################################
|
||||
# Filename : Alertor.py
|
||||
# Description : Alarm by button.
|
||||
# Author : freenove
|
||||
# modification: 2016/06/14
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import math
|
||||
|
||||
buzzerPin = 11 # define the buzzerPin
|
||||
buttonPin = 12 # define the buttonPin
|
||||
|
||||
def setup():
|
||||
global p
|
||||
print 'Program is starting...'
|
||||
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
|
||||
GPIO.setup(buzzerPin, GPIO.OUT) # Set buzzerPin's mode is output
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is input, and pull up to high level(3.3V)
|
||||
p = GPIO.PWM(buzzerPin, 1)
|
||||
p.start(0);
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
if GPIO.input(buttonPin)==GPIO.LOW:
|
||||
alertor()
|
||||
print 'buzzer on ...'
|
||||
else :
|
||||
stopAlertor()
|
||||
print 'buzzer off ...'
|
||||
def alertor():
|
||||
p.start(50)
|
||||
for x in range(0,361): #frequency of the alarm along the sine wave change
|
||||
sinVal = math.sin(x * (math.pi / 180.0)) #calculate the sine value
|
||||
toneVal = 2000 + sinVal * 500 #Add to the resonant frequency with a Weighted
|
||||
p.ChangeFrequency(toneVal) #output PWM
|
||||
time.sleep(0.001)
|
||||
|
||||
def stopAlertor():
|
||||
p.stop()
|
||||
|
||||
def destroy():
|
||||
GPIO.output(buzzerPin, GPIO.LOW) # buzzer off
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
#############################################################################
|
||||
# Filename : PCF8591.py
|
||||
# Description : ADC and DAC
|
||||
# Author : freenove
|
||||
# modification: 2016/06/18
|
||||
########################################################################
|
||||
import smbus
|
||||
import time
|
||||
|
||||
address = 0x48 #default address of PCF8591
|
||||
bus=smbus.SMBus(1)
|
||||
cmd=0x40 #command
|
||||
|
||||
def analogRead(chn):#read ADC value,chn:0,1,2,3
|
||||
value = bus.read_byte_data(address,cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(value):#write DAC value
|
||||
bus.write_byte_data(address,cmd,value)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = analogRead(0) #read the ADC value of channel 0
|
||||
analogWrite(value) #write the DAC value
|
||||
voltage = value / 255.0 * 3.3 #calculate the voltage value
|
||||
print 'ADC Value : %d, Voltage : %.2f'%(value,voltage)
|
||||
time.sleep(0.01)
|
||||
|
||||
def destroy():
|
||||
bus.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print 'Program is starting ... '
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt:
|
||||
destroy()
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
#############################################################################
|
||||
# Filename : Softlight.py
|
||||
# Description : Potentiometer control LED
|
||||
# Author : freenove
|
||||
# modification: 2016/06/18
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import smbus
|
||||
import time
|
||||
|
||||
address = 0x48
|
||||
bus=smbus.SMBus(1)
|
||||
cmd=0x40
|
||||
ledPin = 11
|
||||
|
||||
def analogRead(chn):
|
||||
value = bus.read_byte_data(address,cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(value):
|
||||
bus.write_byte_data(address,cmd,value)
|
||||
|
||||
def setup():
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(ledPin,GPIO.OUT)
|
||||
GPIO.output(ledPin,GPIO.LOW)
|
||||
|
||||
p = GPIO.PWM(ledPin,1000)
|
||||
p.start(0)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = analogRead(0) #read A0 pin
|
||||
p.ChangeDutyCycle(value*100/255) #Convert ADC value to duty cycle of PWM
|
||||
voltage = value / 255.0 * 3.3 #calculate voltage
|
||||
print 'ADC Value : %d, Voltage : %.2f'%(value,voltage)
|
||||
time.sleep(0.01)
|
||||
|
||||
def destroy():
|
||||
bus.close()
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print 'Program is starting ... '
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt:
|
||||
destroy()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user