adding in freenove initial starter kit resources
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(){
|
||||
printf("hello, world!\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**********************************************************************
|
||||
* Filename : Blink.c
|
||||
* Description : Basic usage of GPIO. Let led blink.
|
||||
* auther : www.freenove.com
|
||||
* modification: 2019/12/26
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 0 //define the led pin number
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup(); //Initialize wiringPi.
|
||||
|
||||
pinMode(ledPin, OUTPUT);//Set the pin mode
|
||||
printf("Using pin%d\n",ledPin); //Output information on terminal
|
||||
while(1){
|
||||
digitalWrite(ledPin, HIGH); //Make GPIO output HIGH level
|
||||
printf("led turned on >>>\n"); //Output information on terminal
|
||||
delay(1000); //Wait for 1 second
|
||||
digitalWrite(ledPin, LOW); //Make GPIO output LOW level
|
||||
printf("led turned off <<<\n"); //Output information on terminal
|
||||
delay(1000); //Wait for 1 second
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**********************************************************************
|
||||
* Filename : ButtonLED.c
|
||||
* Description : Control led by button.
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/26
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 0 //define the ledPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup(); //Initialize wiringPi.
|
||||
|
||||
pinMode(ledPin, OUTPUT); //Set ledPin to output
|
||||
pinMode(buttonPin, INPUT);//Set buttonPin to input
|
||||
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to HIGH level
|
||||
while(1){
|
||||
if(digitalRead(buttonPin) == LOW){ //button is pressed
|
||||
digitalWrite(ledPin, HIGH); //Make GPIO output HIGH level
|
||||
printf("Button is pressed, led turned on >>>\n"); //Output information on terminal
|
||||
}
|
||||
else { //button is released
|
||||
digitalWrite(ledPin, LOW); //Make GPIO output LOW level
|
||||
printf("Button is released, led turned off <<<\n"); //Output information on terminal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**********************************************************************
|
||||
* Filename : Tablelamp.c
|
||||
* Description : DIY MINI table lamp
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 stable time for button state
|
||||
int reading;
|
||||
int main(void)
|
||||
{
|
||||
printf("Program is starting...\n");
|
||||
|
||||
wiringPiSetup(); //Initialize wiringPi.
|
||||
|
||||
pinMode(ledPin, OUTPUT); //Set ledPin to output
|
||||
pinMode(buttonPin, INPUT); //Set buttonPin to 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 consider 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, it means the action is pressing
|
||||
if(buttonState == LOW){
|
||||
printf("Button is pressed!\n");
|
||||
ledState = !ledState; //Reverse the LED state
|
||||
if(ledState){
|
||||
printf("turn on LED ...\n");
|
||||
}
|
||||
else {
|
||||
printf("turn off LED ...\n");
|
||||
}
|
||||
}
|
||||
//if the state is high, it means the action is releasing
|
||||
else {
|
||||
printf("Button is released!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
digitalWrite(ledPin,ledState);
|
||||
lastbuttonState = reading;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/**********************************************************************
|
||||
* Filename : LightWater.c
|
||||
* Description : Use LEDBar Graph(10 LED)
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledCounts 10
|
||||
int pins[ledCounts] = {0,1,2,3,4,5,6,8,9,10};
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup(); //Initialize wiringPi.
|
||||
|
||||
for(i=0;i<ledCounts;i++){ //Set pinMode for all led pins to output
|
||||
pinMode(pins[i], OUTPUT);
|
||||
}
|
||||
while(1){
|
||||
for(i=0;i<ledCounts;i++){ // move led(on) from left to right
|
||||
digitalWrite(pins[i],LOW);
|
||||
delay(100);
|
||||
digitalWrite(pins[i],HIGH);
|
||||
}
|
||||
for(i=ledCounts-1;i>-1;i--){ // move led(on) from right to left
|
||||
digitalWrite(pins[i],LOW);
|
||||
delay(100);
|
||||
digitalWrite(pins[i],HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/**********************************************************************
|
||||
* Filename : BreathingLED.c
|
||||
* Description : Make breathing LED with PWM
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
|
||||
#define ledPin 1
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup(); //Initialize wiringPi.
|
||||
|
||||
softPwmCreate(ledPin, 0, 100);//Creat SoftPWM pin
|
||||
|
||||
while(1){
|
||||
for(i=0;i<100;i++){ //make the led brighter
|
||||
softPwmWrite(ledPin, i);
|
||||
delay(20);
|
||||
}
|
||||
delay(300);
|
||||
for(i=100;i>=0;i--){ //make the led darker
|
||||
softPwmWrite(ledPin, i);
|
||||
delay(20);
|
||||
}
|
||||
delay(300);
|
||||
}
|
||||
}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/**********************************************************************
|
||||
* Filename : ColorfulLED.c
|
||||
* Description : Random color change ColorfulLED
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <softPwm.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ledPinRed 0
|
||||
#define ledPinGreen 1
|
||||
#define ledPinBlue 2
|
||||
|
||||
void setupLedPin(void)
|
||||
{
|
||||
softPwmCreate(ledPinRed, 0, 100); //Creat SoftPWM pin for red
|
||||
softPwmCreate(ledPinGreen,0, 100); //Creat SoftPWM pin for green
|
||||
softPwmCreate(ledPinBlue, 0, 100); //Creat SoftPWM pin for blue
|
||||
}
|
||||
|
||||
void setLedColor(int r, int g, int b)
|
||||
{
|
||||
softPwmWrite(ledPinRed, r); //Set the duty cycle
|
||||
softPwmWrite(ledPinGreen, g); //Set the duty cycle
|
||||
softPwmWrite(ledPinBlue, b); //Set the duty cycle
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int r,g,b;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup(); //Initialize wiringPi.
|
||||
|
||||
setupLedPin();
|
||||
while(1){
|
||||
r=random()%100; //get a random in (0,100)
|
||||
g=random()%100; //get a random in (0,100)
|
||||
b=random()%100; //get a random in (0,100)
|
||||
setLedColor(r,g,b);//set random as the duty cycle value
|
||||
printf("r=%d, g=%d, b=%d \n",r,g,b);
|
||||
delay(1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**********************************************************************
|
||||
* Filename : Doorbell.c
|
||||
* Description : Make doorbell with buzzer and button.
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define buzzerPin 0 //define the buzzerPin
|
||||
#define buttonPin 1 //define the buttonPin
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT);
|
||||
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to HIGH level
|
||||
while(1){
|
||||
|
||||
if(digitalRead(buttonPin) == LOW){ //button is pressed
|
||||
digitalWrite(buzzerPin, HIGH); //Turn on buzzer
|
||||
printf("buzzer turned on >>> \n");
|
||||
}
|
||||
else { //button is released
|
||||
digitalWrite(buzzerPin, LOW); //Turn off buzzer
|
||||
printf("buzzer turned off <<< \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**********************************************************************
|
||||
* Filename : Alertor.c
|
||||
* Description : Make Alertor with buzzer and button.
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 alertor is consistent with the sine wave
|
||||
sinVal = sin(x * (M_PI / 180)); //Calculate the sine value
|
||||
toneVal = 2000 + sinVal * 500; //Add the resonant frequency and weighted sine value
|
||||
softToneWrite(pin,toneVal); //output corresponding PWM
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
void stopAlertor(int pin){
|
||||
softToneWrite(pin,0);
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT);
|
||||
softToneCreate(buzzerPin); //set buzzerPin
|
||||
pullUpDnControl(buttonPin, PUD_UP); //pull up to HIGH level
|
||||
while(1){
|
||||
if(digitalRead(buttonPin) == LOW){ //button is pressed
|
||||
alertor(buzzerPin); // turn on buzzer
|
||||
printf("alertor turned on >>> \n");
|
||||
}
|
||||
else { //button is released
|
||||
stopAlertor(buzzerPin); // turn off buzzer
|
||||
printf("alertor turned off <<< \n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**********************************************************************
|
||||
* Filename : ADC.cpp
|
||||
* Description : Use ADC module to read the voltage value of potentiometer.
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/06
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(1){
|
||||
int adcValue = adc->analogRead(0); //read analog value of A0 pin
|
||||
float voltage = (float)adcValue / 255.0 * 3.3; // Calculate voltage
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV\n",adcValue,voltage);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/**********************************************************************
|
||||
* Filename : Softlight.cpp
|
||||
* Description : Use potentiometer to control LED
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/07
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
#define ledPin 0
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
wiringPiSetup();
|
||||
softPwmCreate(ledPin,0,100);
|
||||
while(1){
|
||||
int adcValue = adc->analogRead(0); //read analog value of A0 pin
|
||||
softPwmWrite(ledPin,adcValue*100/255); // Mapping to PWM duty cycle
|
||||
float voltage = (float)adcValue / 255.0 * 3.3; // Calculate voltage
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV\n",adcValue,voltage);
|
||||
delay(30);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**********************************************************************
|
||||
* Filename : Softlight.cpp
|
||||
* Description : Use potentiometer to control LED
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/07
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
#define ledRedPin 3 //define 3 pins for RGBLED
|
||||
#define ledGreenPin 2
|
||||
#define ledBluePin 0
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
wiringPiSetup();
|
||||
softPwmCreate(ledRedPin,0,100); //creat 3 PMW output pins for RGBLED
|
||||
softPwmCreate(ledGreenPin,0,100);
|
||||
softPwmCreate(ledBluePin,0,100);
|
||||
while(1){
|
||||
int val_Red = adc->analogRead(0); //read analog value of 3 potentiometers
|
||||
int val_Green = adc->analogRead(1);
|
||||
int val_Blue = adc->analogRead(2);
|
||||
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;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/**********************************************************************
|
||||
* Filename : Nightlamp.cpp
|
||||
* Description : Photoresistor control LED
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/09
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
#define ledPin 0
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
wiringPiSetup();
|
||||
softPwmCreate(ledPin,0,100);
|
||||
while(1){
|
||||
int value = adc->analogRead(0); //read analog value of A0 pin
|
||||
softPwmWrite(ledPin,value*100/255);
|
||||
float voltage = (float)value / 255.0 * 3.3; // calculate voltage
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**********************************************************************
|
||||
* Filename : Thermometer.cpp
|
||||
* Description : DIY Thermometer
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/09
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
printf("Program is starting ... \n");
|
||||
while(1){
|
||||
int adcValue = adc->analogRead(0); //read analog value A0 pin
|
||||
float voltage = (float)adcValue / 255.0 * 3.3; // calculate voltage
|
||||
float Rt = 10 * voltage / (3.3 - voltage); //calculate resistance value of thermistor
|
||||
float tempK = 1/(1/(273.15 + 25) + log(Rt/10)/3950.0); //calculate temperature (Kelvin)
|
||||
float tempC = tempK -273.15; //calculate temperature (Celsius)
|
||||
printf("ADC value : %d ,\tVoltage : %.2fV, \tTemperature : %.2fC\n",adcValue,voltage,tempC);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/**********************************************************************
|
||||
* Filename : Joystick.cpp
|
||||
* Description : Read Joystick
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/09
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
#define Z_Pin 1 //define pin for axis Z
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
wiringPiSetup();
|
||||
pinMode(Z_Pin,INPUT); //set Z_Pin as input pin and pull-up mode
|
||||
pullUpDnControl(Z_Pin,PUD_UP);
|
||||
while(1){
|
||||
int val_Z = digitalRead(Z_Pin); //read digital value of axis Z
|
||||
int val_Y = adc->analogRead(0); //read analog value of axis X and Y
|
||||
int val_X = adc->analogRead(1);
|
||||
printf("val_X: %d ,\tval_Y: %d ,\tval_Z: %d \n",val_X,val_Y,val_Z);
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/**********************************************************************
|
||||
* Filename : Motor.cpp
|
||||
* Description : Control Motor by L293D
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/03/09
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
#include <softPwm.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <ADCDevice.hpp>
|
||||
|
||||
#define motorPin1 2 //define the pin connected to L293D
|
||||
#define motorPin2 0
|
||||
#define enablePin 3
|
||||
|
||||
ADCDevice *adc; // Define an ADC Device class object
|
||||
|
||||
//Map function: map the value from a range 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,100));
|
||||
printf("The PWM duty cycle is %d%%\n",abs(value)*100/127);//print the PMW duty cycle
|
||||
}
|
||||
int main(void){
|
||||
adc = new ADCDevice();
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
if(adc->detectI2C(0x48)){ // Detect the pcf8591.
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new PCF8591(); // If detected, create an instance of PCF8591.
|
||||
}
|
||||
else if(adc->detectI2C(0x4b)){// Detect the ads7830
|
||||
delete adc; // Free previously pointed memory
|
||||
adc = new ADS7830(); // If detected, create an instance of ADS7830.
|
||||
}
|
||||
else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
return -1;
|
||||
}
|
||||
wiringPiSetup();
|
||||
pinMode(enablePin,OUTPUT);//set mode for the pin
|
||||
pinMode(motorPin1,OUTPUT);
|
||||
pinMode(motorPin2,OUTPUT);
|
||||
softPwmCreate(enablePin,0,100);//define PMW pin
|
||||
while(1){
|
||||
int value = adc->analogRead(0); //read analog value of A0 pin
|
||||
printf("ADC value : %d \n",value);
|
||||
motor(value); //make the motor rotate with speed(analog value of A0 pin)
|
||||
delay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/**********************************************************************
|
||||
* Filename : Relay.c
|
||||
* Description : Control Motor with Button and Relay
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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)
|
||||
{
|
||||
printf("Program is starting...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**********************************************************************
|
||||
* Filename : Sweep.c
|
||||
* Description : Servo sweep
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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){ //Specific 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;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
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;
|
||||
}
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**********************************************************************
|
||||
* Filename : SteppingMotor.c
|
||||
* Description : Drive stepping Motor
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**********************************************************************
|
||||
* Filename : LightWater02.c
|
||||
* Description : Control LED by 74HC595
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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)
|
||||
|
||||
void _shiftOut(int dPin,int cPin,int order,int val){
|
||||
int i;
|
||||
for(i = 0; i < 8; i++){
|
||||
digitalWrite(cPin,LOW);
|
||||
if(order == LSBFIRST){
|
||||
digitalWrite(dPin,((0x01&(val>>i)) == 0x01) ? HIGH : LOW);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
else {//if(order == MSBFIRST){
|
||||
digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ? HIGH : LOW);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
digitalWrite(cPin,HIGH);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char x;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**********************************************************************
|
||||
* Filename : SevenSegmentDisplay.c
|
||||
* Description : Control SevenSegmentDisplay by 74HC595
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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};
|
||||
|
||||
void _shiftOut(int dPin,int cPin,int order,int val){
|
||||
int i;
|
||||
for(i = 0; i < 8; i++){
|
||||
digitalWrite(cPin,LOW);
|
||||
if(order == LSBFIRST){
|
||||
digitalWrite(dPin,((0x01&(val>>i)) == 0x01) ? HIGH : LOW);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
else {//if(order == MSBFIRST){
|
||||
digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ? HIGH : LOW);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
digitalWrite(cPin,HIGH);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/**********************************************************************
|
||||
* Filename : StopWatch.c
|
||||
* Description : Control 4_Digit_7_Segment_Display by 74HC595
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 _shiftOut(int dPin,int cPin,int order,int val){
|
||||
int i;
|
||||
for(i = 0; i < 8; i++){
|
||||
digitalWrite(cPin,LOW);
|
||||
if(order == LSBFIRST){
|
||||
digitalWrite(dPin,((0x01&(val>>i)) == 0x01) ? HIGH : LOW);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
else {//if(order == MSBFIRST){
|
||||
digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ? HIGH : LOW);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
digitalWrite(cPin,HIGH);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
}
|
||||
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
|
||||
int delays = 1;
|
||||
outData(0xff);
|
||||
selectDigit(0x01); //select the first, and display the single digit
|
||||
outData(num[dec%10]);
|
||||
delay(delays); //display duration
|
||||
|
||||
outData(0xff);
|
||||
selectDigit(0x02); //select the second, and display the tens digit
|
||||
outData(num[dec%100/10]);
|
||||
delay(delays);
|
||||
|
||||
outData(0xff);
|
||||
selectDigit(0x04); //select the third, and display the hundreds digit
|
||||
outData(num[dec%1000/100]);
|
||||
delay(delays);
|
||||
|
||||
outData(0xff);
|
||||
selectDigit(0x08); //select the fourth, and display the thousands digit
|
||||
outData(num[dec%10000/1000]);
|
||||
delay(delays);
|
||||
}
|
||||
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;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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],HIGH);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+17
@@ -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"
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/**********************************************************************
|
||||
* Filename : LEDMatrix.c
|
||||
* Description : Control LEDMatrix by 74HC595
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 smile 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, // " "
|
||||
};
|
||||
void _shiftOut(int dPin,int cPin,int order,int val){
|
||||
int i;
|
||||
for(i = 0; i < 8; i++){
|
||||
digitalWrite(cPin,LOW);
|
||||
if(order == LSBFIRST){
|
||||
digitalWrite(dPin,((0x01&(val>>i)) == 0x01) ? HIGH : LOW);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
else {//if(order == MSBFIRST){
|
||||
digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ? HIGH : LOW);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
digitalWrite(cPin,HIGH);
|
||||
delayMicroseconds(10);
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int i,j,k;
|
||||
unsigned char x;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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,MSBFIRST,pic[i]);// first shift data of line information to the first stage 74HC959
|
||||
_shiftOut(dataPin,clockPin,MSBFIRST,~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,MSBFIRST,data[i]);
|
||||
_shiftOut(dataPin,clockPin,MSBFIRST,~x);
|
||||
digitalWrite(latchPin,HIGH);
|
||||
x>>=1;
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/**********************************************************************
|
||||
* Filename : I2CLCD1602.c
|
||||
* Description : Use the LCD display data
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/07/23
|
||||
**********************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
#include <pcf8574.h>
|
||||
#include <lcd.h>
|
||||
#include <time.h>
|
||||
|
||||
int pcf8574_address = 0x27; // PCF8574T:0x27, PCF8574AT:0x3F
|
||||
#define BASE 64 // BASE any number above 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:%02d:%02d:%02d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec); //Display system time on LCD
|
||||
}
|
||||
int detectI2C(int addr){
|
||||
int _fd = wiringPiI2CSetup (addr);
|
||||
if (_fd < 0){
|
||||
printf("Error address : 0x%x \n",addr);
|
||||
return 0 ;
|
||||
}
|
||||
else{
|
||||
if(wiringPiI2CWrite(_fd,0) < 0){
|
||||
printf("Not found device in address 0x%x \n",addr);
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
printf("Found device in address 0x%x \n",addr);
|
||||
return 1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
int main(void){
|
||||
int i;
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
if(detectI2C(0x27)){
|
||||
pcf8574_address = 0x27;
|
||||
}else if(detectI2C(0x3F)){
|
||||
pcf8574_address = 0x3F;
|
||||
}else{
|
||||
printf("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/**********************************************************************
|
||||
* Filename : DHT.hpp
|
||||
* Description : DHT Temperature & Humidity Sensor library for Raspberry.
|
||||
Used for Raspberry Pi.
|
||||
* Program transplantation by Freenove.
|
||||
* Author : freenove
|
||||
* modification: 2020/10/16
|
||||
* Reference : https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib
|
||||
**********************************************************************/
|
||||
#include "DHT.hpp"
|
||||
|
||||
DHT::DHT(){
|
||||
wiringPiSetup();
|
||||
}
|
||||
//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;
|
||||
}
|
||||
// Clear sda
|
||||
pinMode(pin,OUTPUT);
|
||||
digitalWrite(pin,HIGH);
|
||||
delay(500);
|
||||
// Start signal
|
||||
digitalWrite(pin,LOW);
|
||||
delay(wakeupDelay);
|
||||
digitalWrite(pin,HIGH);
|
||||
// delayMicroseconds(40);
|
||||
pinMode(pin,INPUT);
|
||||
|
||||
int32_t loopCnt = DHTLIB_TIMEOUT;
|
||||
t = micros();
|
||||
// Waiting echo
|
||||
while(1){
|
||||
if(digitalRead(pin)==LOW){
|
||||
break;
|
||||
}
|
||||
if((micros() - t) > loopCnt){
|
||||
return DHTLIB_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
loopCnt = DHTLIB_TIMEOUT;
|
||||
t = micros();
|
||||
// Waiting echo low level end
|
||||
while(digitalRead(pin)==LOW){
|
||||
if((micros() - t) > loopCnt){
|
||||
return DHTLIB_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
loopCnt = DHTLIB_TIMEOUT;
|
||||
t = micros();
|
||||
// Waiting echo high level end
|
||||
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);
|
||||
//printf("bits:\t%d,\t%d,\t%d,\t%d,\t%d\n",bits[0],bits[1],bits[2],bits[3],bits[4]);
|
||||
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::readDHT11Once(int pin){
|
||||
int rv ;
|
||||
uint8_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] + bits[3] * 0.1;
|
||||
sum = bits[0] + bits[1] + bits[2] + bits[3];
|
||||
if(bits[4] != sum)
|
||||
return DHTLIB_ERROR_CHECKSUM;
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
|
||||
int DHT::readDHT11(int pin){
|
||||
int chk = DHTLIB_INVALID_VALUE;
|
||||
for (int i = 0; i < 15; i++){
|
||||
chk = readDHT11Once(pin); //read DHT11 and get a return value. Then determine whether data read is normal according to the return value.
|
||||
if(chk == DHTLIB_OK){
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
return chk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/**********************************************************************
|
||||
* Filename : DHT.hpp
|
||||
* Description : DHT Temperature & Humidity Sensor library for Raspberry.
|
||||
Used for Raspberry Pi.
|
||||
* Program transplantation by Freenove.
|
||||
* Author : freenove
|
||||
* modification: 2020/10/16
|
||||
* Reference : https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib
|
||||
**********************************************************************/
|
||||
#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 20
|
||||
#define DHTLIB_DHT_WAKEUP 1
|
||||
|
||||
#define DHTLIB_TIMEOUT 100
|
||||
|
||||
class DHT{
|
||||
public:
|
||||
DHT();
|
||||
double humidity,temperature; //use to store temperature and humidity data read
|
||||
int readDHT11Once(int pin); //read DHT11
|
||||
int readDHT11(int pin); //read DHT11
|
||||
private:
|
||||
uint8_t bits[5]; //Buffer to receiver data
|
||||
int readSensor(int pin,int wakeupDelay); //
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
/**********************************************************************
|
||||
* Filename : DHT11.cpp
|
||||
* Description : Read the temperature and humidity data of DHT11
|
||||
* Author : www.freenove.com
|
||||
* modification: 2020/10/16
|
||||
**********************************************************************/
|
||||
#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, counts; //chk:read the return value of sensor; sumCnt:times of reading sensor
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
while (1){
|
||||
counts++; //counting number of reading times
|
||||
printf("Measurement counts : %d \n", counts);
|
||||
for (int i = 0; i < 15; i++){
|
||||
chk = dht.readDHT11(DHT11_Pin); //read DHT11 and get a return value. Then determine whether data read is normal according to the return value.
|
||||
if(chk == DHTLIB_OK){
|
||||
printf("DHT11,OK! \n");
|
||||
break;
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
printf("Humidity is %.2f %%, \t Temperature is %.2f *C\n\n",dht.humidity, dht.temperature);
|
||||
delay(2000);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|| @file Key.cpp
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact [email protected]
|
||||
||
|
||||
|| @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
|
||||
|| #
|
||||
*/
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
||
|
||||
|| @file Key.h
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact [email protected]
|
||||
||
|
||||
|| @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
|
||||
|| #
|
||||
*/
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.cpp
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact [email protected], [email protected]
|
||||
||
|
||||
|| @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
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
/**********************************************************************
|
||||
* Filename : Keypad.hpp
|
||||
* Description : This library provides a simple interface for using matrix keypads.
|
||||
* Used for Raspberry Pi.
|
||||
* Program transplantation by Freenove.
|
||||
* Author : freenove
|
||||
* modification: 2019/12/28
|
||||
* Reference : https://github.com/Chris--A/Keypad
|
||||
**********************************************************************/
|
||||
#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);
|
||||
}
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.h
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact [email protected], [email protected]
|
||||
||
|
||||
|| @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
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
/**********************************************************************
|
||||
* Filename : Keypad.hpp
|
||||
* Description : This library provides a simple interface for using matrix keypads.
|
||||
* Used for Raspberry Pi.
|
||||
* Program transplantation by Freenove.
|
||||
* Author : freenove
|
||||
* modification: 2019/12/28
|
||||
* Reference : https://github.com/Chris--A/Keypad
|
||||
**********************************************************************/
|
||||
#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
|
||||
|| #
|
||||
*/
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**********************************************************************
|
||||
* Filename : MatrixKeypad.cpp
|
||||
* Description : Obtain the key code of 4x4 Matrix Keypad
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 }; //define the row pins for the keypad
|
||||
byte colPins[COLS] = {12,3, 2, 0 }; //define the column pins for the keypad
|
||||
//create Keypad object
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
int main(){
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**********************************************************************
|
||||
* Filename : SenseLED.c
|
||||
* Description : Control led with infrared Motion sensor
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ledPin 1 //define the ledPin
|
||||
#define sensorPin 0 //define the sensorPin
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(sensorPin, INPUT);
|
||||
|
||||
while(1){
|
||||
|
||||
if(digitalRead(sensorPin) == HIGH){ //if read value of sensor is HIGH level
|
||||
digitalWrite(ledPin, HIGH); //make led on
|
||||
printf("led turned on >>> \n");
|
||||
}
|
||||
else {
|
||||
digitalWrite(ledPin, LOW); //make led off
|
||||
printf("led turned off <<< \n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**********************************************************************
|
||||
* Filename : UltrasonicRanging.c
|
||||
* Description : Get distance via UltrasonicRanging sensor
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 result of ultrasonic module with unit: cm
|
||||
long pingTime;
|
||||
float distance;
|
||||
digitalWrite(trigPin,HIGH); //send 10us high level to trigPin
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(trigPin,LOW);
|
||||
pingTime = pulseIn(echoPin,HIGH,timeOut); //read plus time of echoPin
|
||||
distance = (float)pingTime * 340.0 / 2.0 / 10000.0; //calculate distance with sound speed 340m/s
|
||||
return distance;
|
||||
}
|
||||
|
||||
int main(){
|
||||
printf("Program is starting ... \n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
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 <[email protected]>
|
||||
//
|
||||
// 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 <[email protected]>
|
||||
//
|
||||
// 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_ */
|
||||
+3147
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 <[email protected]>
|
||||
// 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_ */
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**********************************************************************
|
||||
* Filename : MPU6050RAW.c
|
||||
* Description : Read data of MPU6050
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include "I2Cdev.h"
|
||||
#include "MPU6050.h"
|
||||
|
||||
MPU6050 accelgyro; //creat 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 accel/gyro values of MPU6050
|
||||
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;
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/**********************************************************************
|
||||
* Filename : LightWater03.c
|
||||
* Description : Control LED by 74HC595 on DIY circuit board
|
||||
* Author : www.freenove.com
|
||||
* modification: 2019/12/27
|
||||
**********************************************************************/
|
||||
#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 store the pulse width of LED, which will be output to the 8 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; //It works as a delay. The larger, the slower
|
||||
long lastMove; //Record the last time point of the led move
|
||||
|
||||
printf("Program is starting ...\n");
|
||||
|
||||
wiringPiSetup();
|
||||
|
||||
pinMode(dataPin,OUTPUT);
|
||||
pinMode(latchPin,OUTPUT);
|
||||
pinMode(clockPin,OUTPUT);
|
||||
index = 0; //Starting from the array index 0
|
||||
lastMove = millis(); // record 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;
|
||||
for(j=0;j<8;j++){ //Calculate the output state
|
||||
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,12 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Hello.py
|
||||
# Description : Print "Hello World!".
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
|
||||
def Hello():
|
||||
print('Hello World!')
|
||||
|
||||
Hello()
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Blink.py
|
||||
# Description : Basic usage of GPIO. Let led blink.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
ledPin = 11 # define ledPin
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(ledPin, GPIO.OUT) # set the ledPin to OUTPUT mode
|
||||
GPIO.output(ledPin, GPIO.LOW) # make ledPin output LOW level
|
||||
print ('using pin%d'%ledPin)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
GPIO.output(ledPin, GPIO.HIGH) # make ledPin output HIGH level to turn on led
|
||||
print ('led turned on >>>') # print information on terminal
|
||||
time.sleep(1) # Wait for 1 second
|
||||
GPIO.output(ledPin, GPIO.LOW) # make ledPin output LOW level to turn off led
|
||||
print ('led turned off <<<')
|
||||
time.sleep(1) # Wait for 1 second
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup() # Release all GPIO
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... \n')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Blink.py
|
||||
# Description : Basic usage of GPIO. Let led blink.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/26
|
||||
########################################################################
|
||||
from gpiozero import LED
|
||||
from time import sleep
|
||||
|
||||
print ('Program is starting ... ')
|
||||
|
||||
led = LED(17) # define LED pin according to BCM Numbering
|
||||
# led = LED("J8:11") # BOARD Numbering
|
||||
'''
|
||||
# pins numbering, the following lines are all equivalent
|
||||
led = LED("GPIO17") # BCM
|
||||
led = LED("BCM17") # BCM
|
||||
led = LED("BOARD11") # BOARD
|
||||
led = LED("WPI0") # WiringPi
|
||||
led = LED("J8:11") # BOARD
|
||||
'''
|
||||
|
||||
while True:
|
||||
led.on() # turn on LED
|
||||
print ('led turned on >>>') # print message on terminal
|
||||
sleep(1) # wait 1 second
|
||||
led.off() # turn off LED
|
||||
print ('led turned off <<<')
|
||||
sleep(1) # wait 1 second
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ButtonLED.py
|
||||
# Description : Control led with button
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
ledPin = 11 # define ledPin
|
||||
buttonPin = 12 # define buttonPin
|
||||
|
||||
def setup():
|
||||
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(ledPin, GPIO.OUT) # set ledPin to OUTPUT mode
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set buttonPin to PULL UP INPUT mode
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
if GPIO.input(buttonPin)==GPIO.LOW: # if button is pressed
|
||||
GPIO.output(ledPin,GPIO.HIGH) # turn on led
|
||||
print ('led turned on >>>') # print information on terminal
|
||||
else : # if button is relessed
|
||||
GPIO.output(ledPin,GPIO.LOW) # turn off led
|
||||
print ('led turned off <<<')
|
||||
|
||||
def destroy():
|
||||
GPIO.output(ledPin, GPIO.LOW) # turn off led
|
||||
GPIO.cleanup() # Release GPIO resource
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ButtonLED.py
|
||||
# Description : Control led with button.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
from gpiozero import LED, Button
|
||||
from signal import pause
|
||||
|
||||
print ('Program is starting ... ')
|
||||
|
||||
led = LED(17) # define LED pin according to BCM Numbering
|
||||
button = Button(18) # define Button pin according to BCM Numbering
|
||||
|
||||
def onButtonPressed():
|
||||
led.on()
|
||||
print("Button is pressed, led turned on >>>")
|
||||
|
||||
def onButtonReleased():
|
||||
led.off()
|
||||
print("Button is released, led turned on <<<")
|
||||
|
||||
button.when_pressed = onButtonPressed
|
||||
button.when_released = onButtonReleased
|
||||
|
||||
pause()
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Tablelamp.py
|
||||
# Description : a DIY MINI table lamp
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
ledPin = 11 # define ledPin
|
||||
buttonPin = 12 # define buttonPin
|
||||
ledState = False
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(ledPin, GPIO.OUT) # set ledPin to OUTPUT mode
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set buttonPin to PULL UP INPUT mode
|
||||
|
||||
def buttonEvent(channel): # When button is pressed, this function will be executed
|
||||
global ledState
|
||||
print ('buttonEvent GPIO%d' %channel)
|
||||
ledState = not ledState
|
||||
if ledState :
|
||||
print ('Led turned on >>>')
|
||||
else :
|
||||
print ('Led turned off <<<')
|
||||
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.cleanup() # Release GPIO resource
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Tablelamp.py
|
||||
# Description : DIY MINI table lamp
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
from gpiozero import LED, Button
|
||||
from signal import pause
|
||||
|
||||
print ('Program is starting ... ')
|
||||
|
||||
led = LED(17) # define LED pin according to BCM Numbering
|
||||
button = Button(18) # define Button pin according to BCM Numbering
|
||||
|
||||
def onButtonPressed():
|
||||
led.toggle()
|
||||
if led.is_lit :
|
||||
print("Led turned on >>>")
|
||||
else :
|
||||
print("Led turned off <<<")
|
||||
|
||||
button.when_pressed = onButtonPressed
|
||||
|
||||
pause()
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : LightWater.py
|
||||
# Description : Use LEDBar Graph(10 LED)
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
ledPins = [11, 12, 13, 15, 16, 18, 22, 3, 5, 24]
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(ledPins, GPIO.OUT) # set all ledPins to OUTPUT mode
|
||||
GPIO.output(ledPins, GPIO.HIGH) # make all ledPins output HIGH level, turn off all led
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for pin in ledPins: # make led(on) move from left to right
|
||||
GPIO.output(pin, GPIO.LOW)
|
||||
time.sleep(0.1)
|
||||
GPIO.output(pin, GPIO.HIGH)
|
||||
for pin in ledPins[::-1]: # make led(on) move from right to left
|
||||
GPIO.output(pin, GPIO.LOW)
|
||||
time.sleep(0.1)
|
||||
GPIO.output(pin, GPIO.HIGH)
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup() # Release all GPIO
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : LightWater.py
|
||||
# Description : Use LEDBar Graph(10 LED)
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
from gpiozero import LEDBoard
|
||||
from time import sleep
|
||||
|
||||
print ('Program is starting ... ')
|
||||
|
||||
ledPins = ["J8:11", "J8:12","J8:13","J8:15","J8:16","J8:18","J8:22","J8:3","J8:5","J8:24"]
|
||||
|
||||
leds = LEDBoard(*ledPins, active_high=False)
|
||||
|
||||
while True:
|
||||
for index in range(0,len(ledPins),1): #move led(on) from left to right
|
||||
leds.on(index)
|
||||
sleep(0.1)
|
||||
leds.off(index)
|
||||
for index in range(len(ledPins)-1,-1,-1): #move led(on) from right to left
|
||||
leds.on(index)
|
||||
sleep(0.1)
|
||||
leds.off(index)
|
||||
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : BreathingLED.py
|
||||
# Description : Breathing LED
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
LedPin = 12 # define the LedPin
|
||||
|
||||
def setup():
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(LedPin, GPIO.OUT) # set LedPin to OUTPUT mode
|
||||
GPIO.output(LedPin, GPIO.LOW) # make ledPin output LOW level to turn off LED
|
||||
|
||||
p = GPIO.PWM(LedPin, 500) # set PWM Frequence to 500Hz
|
||||
p.start(0) # set initial Duty Cycle to 0
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for dc in range(0, 101, 1): # make the led brighter
|
||||
p.ChangeDutyCycle(dc) # set dc value as the duty cycle
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
for dc in range(100, -1, -1): # make the led darker
|
||||
p.ChangeDutyCycle(dc) # set dc value as the duty cycle
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
|
||||
def destroy():
|
||||
p.stop() # stop PWM
|
||||
GPIO.cleanup() # Release all GPIO
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ColorfulLED.py
|
||||
# Description : Random color change ColorfulLED
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import random
|
||||
|
||||
pins = [11, 12, 13] # define the pins for R:11,G:12,B:13
|
||||
|
||||
def setup():
|
||||
global pwmRed,pwmGreen,pwmBlue
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(pins, GPIO.OUT) # set RGBLED pins to OUTPUT mode
|
||||
GPIO.output(pins, GPIO.HIGH) # make RGBLED pins output HIGH level
|
||||
pwmRed = GPIO.PWM(pins[0], 2000) # set PWM Frequence to 2kHz
|
||||
pwmGreen = GPIO.PWM(pins[1], 2000) # set PWM Frequence to 2kHz
|
||||
pwmBlue = GPIO.PWM(pins[2], 2000) # set PWM Frequence to 2kHz
|
||||
pwmRed.start(0) # set initial Duty Cycle to 0
|
||||
pwmGreen.start(0)
|
||||
pwmBlue.start(0)
|
||||
|
||||
def setColor(r_val,g_val,b_val): # change duty cycle for three pins to r_val,g_val,b_val
|
||||
pwmRed.ChangeDutyCycle(r_val) # change pwmRed duty cycle to r_val
|
||||
pwmGreen.ChangeDutyCycle(g_val)
|
||||
pwmBlue.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(1)
|
||||
|
||||
def destroy():
|
||||
pwmRed.stop()
|
||||
pwmGreen.stop()
|
||||
pwmBlue.stop()
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Doorbell.py
|
||||
# Description : Make doorbell with buzzer and button
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
buzzerPin = 11 # define buzzerPin
|
||||
buttonPin = 12 # define buttonPin
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(buzzerPin, GPIO.OUT) # set buzzerPin to OUTPUT mode
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set buttonPin to PULL UP INPUT mode
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
if GPIO.input(buttonPin)==GPIO.LOW: # if button is pressed
|
||||
GPIO.output(buzzerPin,GPIO.HIGH) # turn on buzzer
|
||||
print ('buzzer turned on >>>')
|
||||
else : # if button is relessed
|
||||
GPIO.output(buzzerPin,GPIO.LOW) # turn off buzzer
|
||||
print ('buzzer turned off <<<')
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup() # Release all GPIO
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Doorbell.py
|
||||
# Description : Make doorbell with buzzer and button
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
from gpiozero import LED, Button
|
||||
from signal import pause
|
||||
|
||||
print ('Program is starting...')
|
||||
|
||||
led = LED(17)
|
||||
button = Button(18)
|
||||
|
||||
def onButtonPressed():
|
||||
led.on()
|
||||
print("Button is pressed, led turned on >>>")
|
||||
|
||||
def onButtonReleased():
|
||||
led.off()
|
||||
print("Button is released, led turned on <<<")
|
||||
|
||||
button.when_pressed = onButtonPressed
|
||||
button.when_released = onButtonReleased
|
||||
|
||||
pause()
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Alertor.py
|
||||
# Description : Make Alertor with buzzer and button
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import math
|
||||
|
||||
buzzerPin = 11 # define the buzzerPin
|
||||
buttonPin = 12 # define the buttonPin
|
||||
|
||||
def setup():
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD) # Use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(buzzerPin, GPIO.OUT) # set RGBLED pins to OUTPUT mode
|
||||
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin to INPUT mode, 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 ('alertor turned on >>> ')
|
||||
else :
|
||||
stopAlertor()
|
||||
print ('alertor turned off <<<')
|
||||
def alertor():
|
||||
p.start(50)
|
||||
for x in range(0,361): # Make frequency of the alertor consistent with the sine wave
|
||||
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) # Change Frequency of PWM to toneVal
|
||||
time.sleep(0.001)
|
||||
|
||||
def stopAlertor():
|
||||
p.stop()
|
||||
|
||||
def destroy():
|
||||
GPIO.output(buzzerPin, GPIO.LOW) # Turn off buzzer
|
||||
p.stop() # stop PWM
|
||||
GPIO.cleanup() # Release GPIO resource
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADC.py
|
||||
# Description : Use ADC module to read the voltage value of potentiometer.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/03/06
|
||||
########################################################################
|
||||
import time
|
||||
from ADCDevice import *
|
||||
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = adc.analogRead(0) # read the ADC value of channel 0
|
||||
voltage = value / 255.0 * 3.3 # calculate the voltage value
|
||||
print ('ADC Value : %d, Voltage : %.2f'%(value,voltage))
|
||||
time.sleep(0.1)
|
||||
|
||||
def destroy():
|
||||
adc.close()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
try:
|
||||
setup()
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADC.py
|
||||
# Description : Use ADC module to read the voltage value of potentiometer.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/03/06
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
from ADCDevice import *
|
||||
|
||||
ledPin = 11
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(ledPin,GPIO.OUT)
|
||||
p = GPIO.PWM(ledPin,1000)
|
||||
p.start(0)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = adc.analogRead(0) # read the ADC value of channel 0
|
||||
p.ChangeDutyCycle(value*100/255) # Mapping to PWM duty cycle
|
||||
voltage = value / 255.0 * 3.3 # calculate the voltage value
|
||||
print ('ADC Value : %d, Voltage : %.2f'%(value,voltage))
|
||||
time.sleep(0.03)
|
||||
|
||||
def destroy():
|
||||
p.stop() # stop PWM
|
||||
GPIO.cleanup()
|
||||
adc.close()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
try:
|
||||
setup()
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : Softlight.py
|
||||
# Description : Control RGBLED with Potentiometer
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/03/09
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
from ADCDevice import *
|
||||
|
||||
ledRedPin = 15 # define 3 pins for RGBLED
|
||||
ledGreenPin = 13
|
||||
ledBluePin = 11
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
|
||||
global p_Red,p_Green,p_Blue
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(ledRedPin,GPIO.OUT) # set RGBLED pins to OUTPUT mode
|
||||
GPIO.setup(ledGreenPin,GPIO.OUT)
|
||||
GPIO.setup(ledBluePin,GPIO.OUT)
|
||||
|
||||
p_Red = GPIO.PWM(ledRedPin,1000) # configure PMW for RGBLED pins, set PWM Frequence to 1kHz
|
||||
p_Red.start(0)
|
||||
p_Green = GPIO.PWM(ledGreenPin,1000)
|
||||
p_Green.start(0)
|
||||
p_Blue = GPIO.PWM(ledBluePin,1000)
|
||||
p_Blue.start(0)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value_Red = adc.analogRead(0) # read ADC value of 3 potentiometers
|
||||
value_Green = adc.analogRead(1)
|
||||
value_Blue = adc.analogRead(2)
|
||||
p_Red.ChangeDutyCycle(value_Red*100/255) # map the read value of potentiometers into PWM value and output it
|
||||
p_Green.ChangeDutyCycle(value_Green*100/255)
|
||||
p_Blue.ChangeDutyCycle(value_Blue*100/255)
|
||||
# print read ADC value
|
||||
print ('ADC Value value_Red: %d ,\tvlue_Green: %d ,\tvalue_Blue: %d'%(value_Red,value_Green,value_Blue))
|
||||
time.sleep(0.01)
|
||||
|
||||
def destroy():
|
||||
adc.close()
|
||||
p_Red.stop() # stop PWM
|
||||
p_Green.stop() # stop PWM
|
||||
p_Blue.stop() # stop PWM
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : Nightlamp.py
|
||||
# Description : Control LED with Photoresistor
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/03/09
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
from ADCDevice import *
|
||||
|
||||
ledPin = 11 # define ledPin
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(ledPin,GPIO.OUT) # set ledPin to OUTPUT mode
|
||||
GPIO.output(ledPin,GPIO.LOW)
|
||||
|
||||
p = GPIO.PWM(ledPin,1000) # set PWM Frequence to 1kHz
|
||||
p.start(0)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = adc.analogRead(0) # read the ADC value of channel 0
|
||||
p.ChangeDutyCycle(value*100/255)
|
||||
voltage = value / 255.0 * 3.3
|
||||
print ('ADC Value : %d, Voltage : %.2f'%(value,voltage))
|
||||
time.sleep(0.01)
|
||||
|
||||
def destroy():
|
||||
adc.close()
|
||||
p.stop() # stop PWM
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : Thermometer.py
|
||||
# Description : DIY Thermometer
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/03/09
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import math
|
||||
from ADCDevice import *
|
||||
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = adc.analogRead(0) # read ADC value A0 pin
|
||||
voltage = value / 255.0 * 3.3 # calculate voltage
|
||||
Rt = 10 * voltage / (3.3 - voltage) # calculate resistance value of thermistor
|
||||
tempK = 1/(1/(273.15 + 25) + math.log(Rt/10)/3950.0) # calculate temperature (Kelvin)
|
||||
tempC = tempK -273.15 # calculate temperature (Celsius)
|
||||
print ('ADC Value : %d, Voltage : %.2f, Temperature : %.2f'%(value,voltage,tempC))
|
||||
time.sleep(0.01)
|
||||
|
||||
def destroy():
|
||||
adc.close()
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : Joystick.py
|
||||
# Description : Read Joystick state
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/03/09
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
from ADCDevice import *
|
||||
|
||||
Z_Pin = 12 # define Z_Pin
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(Z_Pin,GPIO.IN,GPIO.PUD_UP) # set Z_Pin to pull-up mode
|
||||
def loop():
|
||||
while True:
|
||||
val_Z = GPIO.input(Z_Pin) # read digital value of axis Z
|
||||
val_Y = adc.analogRead(0) # read analog value of axis X and Y
|
||||
val_X = adc.analogRead(1)
|
||||
print ('value_X: %d ,\tvlue_Y: %d ,\tvalue_Z: %d'%(val_X,val_Y,val_Z))
|
||||
time.sleep(0.01)
|
||||
|
||||
def destroy():
|
||||
adc.close()
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('Program is starting ... ') # Program entrance
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : ADCDevice.py
|
||||
# Description : Freenove ADC Module library.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2020/04/21
|
||||
########################################################################
|
||||
|
||||
import smbus
|
||||
|
||||
class ADCDevice(object):
|
||||
def __init__(self):
|
||||
self.cmd = 0
|
||||
self.address = 0
|
||||
self.bus=smbus.SMBus(1)
|
||||
# print("ADCDevice init")
|
||||
|
||||
def detectI2C(self,addr):
|
||||
try:
|
||||
self.bus.write_byte(addr,0)
|
||||
print("Found device in address 0x%x"%(addr))
|
||||
return True
|
||||
except:
|
||||
print("Not found device in address 0x%x"%(addr))
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.bus.close()
|
||||
|
||||
class PCF8591(ADCDevice):
|
||||
def __init__(self):
|
||||
super(PCF8591, self).__init__()
|
||||
self.cmd = 0x40 # The default command for PCF8591 is 0x40.
|
||||
self.address = 0x48 # 0x48 is the default i2c address for PCF8591 Module.
|
||||
|
||||
def analogRead(self, chn): # PCF8591 has 4 ADC input pins, chn:0,1,2,3
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
value = self.bus.read_byte_data(self.address, self.cmd+chn)
|
||||
return value
|
||||
|
||||
def analogWrite(self,value): # write DAC value
|
||||
self.bus.write_byte_data(address,cmd,value)
|
||||
|
||||
class ADS7830(ADCDevice):
|
||||
def __init__(self):
|
||||
super(ADS7830, self).__init__()
|
||||
self.cmd = 0x84
|
||||
self.address = 0x4b # 0x4b is the default i2c address for ADS7830 Module.
|
||||
|
||||
def analogRead(self, chn): # ADS7830 has 8 ADC input pins, chn:0,1,2,3,4,5,6,7
|
||||
value = self.bus.read_byte_data(self.address, self.cmd|(((chn<<2 | chn>>1)&0x07)<<4))
|
||||
return value
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : Motor.py
|
||||
# Description : Control Motor with L293D
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
from ADCDevice import *
|
||||
|
||||
# define the pins connected to L293D
|
||||
motoRPin1 = 13
|
||||
motoRPin2 = 11
|
||||
enablePin = 15
|
||||
adc = ADCDevice() # Define an ADCDevice class object
|
||||
|
||||
def setup():
|
||||
global adc
|
||||
if(adc.detectI2C(0x48)): # Detect the pcf8591.
|
||||
adc = PCF8591()
|
||||
elif(adc.detectI2C(0x4b)): # Detect the ads7830
|
||||
adc = ADS7830()
|
||||
else:
|
||||
print("No correct I2C address found, \n"
|
||||
"Please use command 'i2cdetect -y 1' to check the I2C address! \n"
|
||||
"Program Exit. \n");
|
||||
exit(-1)
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(motoRPin1,GPIO.OUT) # set pins to OUTPUT mode
|
||||
GPIO.setup(motoRPin2,GPIO.OUT)
|
||||
GPIO.setup(enablePin,GPIO.OUT)
|
||||
|
||||
p = GPIO.PWM(enablePin,1000) # creat PWM and set Frequence to 1KHz
|
||||
p.start(0)
|
||||
|
||||
# mapNUM function: map the value from a range of mapping to another range.
|
||||
def mapNUM(value,fromLow,fromHigh,toLow,toHigh):
|
||||
return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow
|
||||
|
||||
# motor function: determine the direction and speed of the motor according to the input ADC value input
|
||||
def motor(ADC):
|
||||
value = ADC -128
|
||||
if (value > 0): # make motor turn forward
|
||||
GPIO.output(motoRPin1,GPIO.HIGH) # motoRPin1 output HIHG level
|
||||
GPIO.output(motoRPin2,GPIO.LOW) # motoRPin2 output LOW level
|
||||
print ('Turn Forward...')
|
||||
elif (value < 0): # make motor turn backward
|
||||
GPIO.output(motoRPin1,GPIO.LOW)
|
||||
GPIO.output(motoRPin2,GPIO.HIGH)
|
||||
print ('Turn Backward...')
|
||||
else :
|
||||
GPIO.output(motoRPin1,GPIO.LOW)
|
||||
GPIO.output(motoRPin2,GPIO.LOW)
|
||||
print ('Motor Stop...')
|
||||
p.start(mapNUM(abs(value),0,128,0,100))
|
||||
print ('The PWM duty cycle is %d%%\n'%(abs(value)*100/127)) # print PMW duty cycle.
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
value = adc.analogRead(0) # read ADC value of channel 0
|
||||
print ('ADC Value : %d'%(value))
|
||||
motor(value)
|
||||
time.sleep(0.2)
|
||||
|
||||
def destroy():
|
||||
p.stop() # stop PWM
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting ... ')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Relay.py
|
||||
# Description : Control Relay and Motor via Button
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
relayPin = 11 # define the relayPin
|
||||
buttonPin = 12 # define the buttonPin
|
||||
debounceTime = 50
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(relayPin, GPIO.OUT) # set relayPin to OUTPUT mode
|
||||
GPIO.setup(buttonPin, GPIO.IN) # set buttonPin to INTPUT mode
|
||||
|
||||
def loop():
|
||||
relayState = False
|
||||
lastChangeTime = round(time.time()*1000)
|
||||
buttonState = GPIO.HIGH
|
||||
lastButtonState = GPIO.HIGH
|
||||
reading = GPIO.HIGH
|
||||
while True:
|
||||
reading = GPIO.input(buttonPin)
|
||||
if reading != lastButtonState :
|
||||
lastChangeTime = round(time.time()*1000)
|
||||
if ((round(time.time()*1000) - lastChangeTime) > debounceTime):
|
||||
if reading != buttonState :
|
||||
buttonState = reading;
|
||||
if buttonState == GPIO.LOW:
|
||||
print("Button is pressed!")
|
||||
relayState = not relayState
|
||||
if relayState:
|
||||
print("Turn on relay ...")
|
||||
else :
|
||||
print("Turn off relay ... ")
|
||||
else :
|
||||
print("Button is released!")
|
||||
GPIO.output(relayPin,relayState)
|
||||
lastButtonState = reading # lastButtonState store latest state
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Sweep.py
|
||||
# Description : Servo sweep
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
OFFSET_DUTY = 0.5 # define pulse offset of servo
|
||||
SERVO_MIN_DUTY = 2.5 + OFFSET_DUTY # define pulse duty cycle for minimum angle of servo
|
||||
SERVO_MAX_DUTY = 12.5 + OFFSET_DUTY # define pulse duty cycle for maximum angle of servo
|
||||
SERVO_DELAY_SEC = 0.001
|
||||
servoPin = 12
|
||||
|
||||
def setup():
|
||||
global p
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(servoPin, GPIO.OUT) # Set servoPin to OUTPUT mode
|
||||
GPIO.output(servoPin, GPIO.LOW) # Make servoPin output LOW level
|
||||
|
||||
p = GPIO.PWM(servoPin, 50) # set Frequence to 50Hz
|
||||
p.start(0) # Set initial Duty Cycle to 0
|
||||
|
||||
def servoWrite(angle): # make the servo rotate to specific angle, 0-180
|
||||
if(angle < 0):
|
||||
angle = 0
|
||||
elif(angle > 180):
|
||||
angle = 180
|
||||
dc = SERVO_MIN_DUTY + (SERVO_MAX_DUTY - SERVO_MIN_DUTY) * angle / 180.0 # map the angle to duty cycle
|
||||
p.ChangeDutyCycle(dc)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for angle in range(0, 181, 1): # make servo rotate from 0 to 180 deg
|
||||
servoWrite(angle)
|
||||
time.sleep(SERVO_DELAY_SEC)
|
||||
time.sleep(0.5)
|
||||
for angle in range(180, -1, -1): # make servo rotate from 180 to 0 deg
|
||||
servoWrite(angle)
|
||||
time.sleep(SERVO_DELAY_SEC)
|
||||
time.sleep(0.5)
|
||||
|
||||
def destroy():
|
||||
p.stop()
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : SteppingMotor.py
|
||||
# Description : Drive SteppingMotor
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
motorPins = (12, 16, 18, 22) # define pins connected to four phase ABCD of stepper motor
|
||||
CCWStep = (0x01,0x02,0x04,0x08) # define power supply order for rotating anticlockwise
|
||||
CWStep = (0x08,0x04,0x02,0x01) # define power supply order for rotating clockwise
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
for pin in motorPins:
|
||||
GPIO.setup(pin,GPIO.OUT)
|
||||
|
||||
# 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
|
||||
def moveOnePeriod(direction,ms):
|
||||
for j in range(0,4,1): # cycle for power supply order
|
||||
for i in range(0,4,1): # assign to each pin
|
||||
if (direction == 1):# power supply order clockwise
|
||||
GPIO.output(motorPins[i],((CCWStep[j] == 1<<i) and GPIO.HIGH or GPIO.LOW))
|
||||
else : # power supply order anticlockwise
|
||||
GPIO.output(motorPins[i],((CWStep[j] == 1<<i) and GPIO.HIGH or GPIO.LOW))
|
||||
if(ms<3): # the delay can not be less than 3ms, otherwise it will exceed speed limit of the motor
|
||||
ms = 3
|
||||
time.sleep(ms*0.001)
|
||||
|
||||
# continuous rotation function, the parameter steps specifies the rotation cycles, every four steps is a cycle
|
||||
def moveSteps(direction, ms, steps):
|
||||
for i in range(steps):
|
||||
moveOnePeriod(direction, ms)
|
||||
|
||||
# function used to stop motor
|
||||
def motorStop():
|
||||
for i in range(0,4,1):
|
||||
GPIO.output(motorPins[i],GPIO.LOW)
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
moveSteps(1,3,512) # rotating 360 deg clockwise, a total of 2048 steps in a circle, 512 cycles
|
||||
time.sleep(0.5)
|
||||
moveSteps(0,3,512) # rotating 360 deg anticlockwise
|
||||
time.sleep(0.5)
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup() # Release resource
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : LightWater02.py
|
||||
# Description : Control LED with 74HC595
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
# Defines the data bit that is transmitted preferentially in the shiftOut function.
|
||||
LSBFIRST = 1
|
||||
MSBFIRST = 2
|
||||
# define the pins for 74HC595
|
||||
dataPin = 11 # DS Pin of 74HC595(Pin14)
|
||||
latchPin = 13 # ST_CP Pin of 74HC595(Pin12)
|
||||
clockPin = 15 # CH_CP Pin of 74HC595(Pin11)
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(dataPin, GPIO.OUT) # set pin to OUTPUT mode
|
||||
GPIO.setup(latchPin, GPIO.OUT)
|
||||
GPIO.setup(clockPin, GPIO.OUT)
|
||||
|
||||
# shiftOut function, use bit serial transmission.
|
||||
def shiftOut(dPin,cPin,order,val):
|
||||
for i in range(0,8):
|
||||
GPIO.output(cPin,GPIO.LOW);
|
||||
if(order == LSBFIRST):
|
||||
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
|
||||
elif(order == MSBFIRST):
|
||||
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
|
||||
GPIO.output(cPin,GPIO.HIGH);
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
x=0x01
|
||||
for i in range(0,8):
|
||||
GPIO.output(latchPin,GPIO.LOW) # Output low level to latchPin
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,x) # Send serial data to 74HC595
|
||||
GPIO.output(latchPin,GPIO.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.
|
||||
time.sleep(0.1)
|
||||
x=0x80
|
||||
for i in range(0,8):
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,x)
|
||||
GPIO.output(latchPin,GPIO.HIGH)
|
||||
x>>=1
|
||||
time.sleep(0.1)
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...' )
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : SevenSegmentDisplay.py
|
||||
# Description : Control SevenSegmentDisplay with 74HC595
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
LSBFIRST = 1
|
||||
MSBFIRST = 2
|
||||
# define the pins for 74HC595
|
||||
dataPin = 11 # DS Pin of 74HC595(Pin14)
|
||||
latchPin = 13 # ST_CP Pin of 74HC595(Pin12)
|
||||
clockPin = 15 # CH_CP Pin of 74HC595(Pin11)
|
||||
# SevenSegmentDisplay display the character "0"- "F" successively
|
||||
num = [0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e]
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(dataPin, GPIO.OUT)
|
||||
GPIO.setup(latchPin, GPIO.OUT)
|
||||
GPIO.setup(clockPin, GPIO.OUT)
|
||||
|
||||
def shiftOut(dPin,cPin,order,val):
|
||||
for i in range(0,8):
|
||||
GPIO.output(cPin,GPIO.LOW);
|
||||
if(order == LSBFIRST):
|
||||
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
|
||||
elif(order == MSBFIRST):
|
||||
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
|
||||
GPIO.output(cPin,GPIO.HIGH);
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for i in range(0,len(num)):
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,num[i]) # Send serial data to 74HC595
|
||||
GPIO.output(latchPin,GPIO.HIGH)
|
||||
time.sleep(0.5)
|
||||
for i in range(0,len(num)):
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,num[i]&0x7f) # Use "&0x7f" to display the decimal point.
|
||||
GPIO.output(latchPin,GPIO.HIGH)
|
||||
time.sleep(0.5)
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...' )
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : StopWatch.py
|
||||
# Description : Control 4_Digit_7_Segment_Display with 74HC595
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/27
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import threading
|
||||
|
||||
LSBFIRST = 1
|
||||
MSBFIRST = 2
|
||||
# define the pins connect to 74HC595
|
||||
dataPin = 18 # DS Pin of 74HC595
|
||||
latchPin = 16 # ST_CP Pin of 74HC595
|
||||
clockPin = 12 # SH_CP Pin of 74HC595
|
||||
num = (0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90)
|
||||
digitPin = (11,13,15,19) # Define the pin of 7-segment display common end
|
||||
counter = 0 # Variable counter, the number will be dislayed by 7-segment display
|
||||
t = 0 # define the Timer object
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(dataPin, GPIO.OUT) # Set pin mode to OUTPUT
|
||||
GPIO.setup(latchPin, GPIO.OUT)
|
||||
GPIO.setup(clockPin, GPIO.OUT)
|
||||
for pin in digitPin:
|
||||
GPIO.setup(pin,GPIO.OUT)
|
||||
|
||||
def shiftOut(dPin,cPin,order,val):
|
||||
for i in range(0,8):
|
||||
GPIO.output(cPin,GPIO.LOW);
|
||||
if(order == LSBFIRST):
|
||||
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
|
||||
elif(order == MSBFIRST):
|
||||
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
|
||||
GPIO.output(cPin,GPIO.HIGH)
|
||||
|
||||
def outData(data): # function used to output data for 74HC595
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,data)
|
||||
GPIO.output(latchPin,GPIO.HIGH)
|
||||
|
||||
def selectDigit(digit): # Open one of the 7-segment display and close the remaining three, the parameter digit is optional for 1,2,4,8
|
||||
GPIO.output(digitPin[0],GPIO.LOW if ((digit&0x08) == 0x08) else GPIO.HIGH)
|
||||
GPIO.output(digitPin[1],GPIO.LOW if ((digit&0x04) == 0x04) else GPIO.HIGH)
|
||||
GPIO.output(digitPin[2],GPIO.LOW if ((digit&0x02) == 0x02) else GPIO.HIGH)
|
||||
GPIO.output(digitPin[3],GPIO.LOW if ((digit&0x01) == 0x01) else GPIO.HIGH)
|
||||
|
||||
def display(dec): # display function for 7-segment display
|
||||
outData(0xff) # eliminate residual display
|
||||
selectDigit(0x01) # Select the first, and display the single digit
|
||||
outData(num[dec%10])
|
||||
time.sleep(0.003) # display duration
|
||||
outData(0xff)
|
||||
selectDigit(0x02) # Select the second, and display the tens digit
|
||||
outData(num[dec%100//10])
|
||||
time.sleep(0.003)
|
||||
outData(0xff)
|
||||
selectDigit(0x04) # Select the third, and display the hundreds digit
|
||||
outData(num[dec%1000//100])
|
||||
time.sleep(0.003)
|
||||
outData(0xff)
|
||||
selectDigit(0x08) # Select the fourth, and display the thousands digit
|
||||
outData(num[dec%10000//1000])
|
||||
time.sleep(0.003)
|
||||
def timer():
|
||||
global counter
|
||||
global t
|
||||
t = threading.Timer(1.0,timer) # reset time of timer to 1s
|
||||
t.start() # Start timing
|
||||
counter+=1
|
||||
print ("counter : %d"%counter)
|
||||
|
||||
def loop():
|
||||
global t
|
||||
global counter
|
||||
t = threading.Timer(1.0,timer) # set the timer
|
||||
t.start() # Start timing
|
||||
while True:
|
||||
display(counter) # display the number counter
|
||||
|
||||
def destroy():
|
||||
global t
|
||||
GPIO.cleanup()
|
||||
t.cancel()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...' )
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : LEDMatrix.py
|
||||
# Description : Control LEDMatrix with 74HC595
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
LSBFIRST = 1
|
||||
MSBFIRST = 2
|
||||
# define the pins connect to 74HC595
|
||||
dataPin = 11 # DS Pin of 74HC595(Pin14)
|
||||
latchPin = 13 # ST_CP Pin of 74HC595(Pin12)
|
||||
clockPin = 15 # SH_CP Pin of 74HC595(Pin11)
|
||||
pic = [0x1c,0x22,0x51,0x45,0x45,0x51,0x22,0x1c] # data of smiling face
|
||||
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, # " "
|
||||
]
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(dataPin, GPIO.OUT)
|
||||
GPIO.setup(latchPin, GPIO.OUT)
|
||||
GPIO.setup(clockPin, GPIO.OUT)
|
||||
|
||||
def shiftOut(dPin,cPin,order,val):
|
||||
for i in range(0,8):
|
||||
GPIO.output(cPin,GPIO.LOW);
|
||||
if(order == LSBFIRST):
|
||||
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
|
||||
elif(order == MSBFIRST):
|
||||
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
|
||||
GPIO.output(cPin,GPIO.HIGH);
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
for j in range(0,500): # Repeat enough times to display the smiling face a period of time
|
||||
x=0x80
|
||||
for i in range(0,8):
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,pic[i]) #first shift data of line information to first stage 74HC959
|
||||
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,~x) #then shift data of column information to second stage 74HC959
|
||||
GPIO.output(latchPin,GPIO.HIGH) # Output data of two stage 74HC595 at the same time
|
||||
time.sleep(0.001) # display the next column
|
||||
x>>=1
|
||||
for k in range(0,len(data)-8): #len(data) total number of "0-F" columns
|
||||
for j in range(0,20): # 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 in range(k,k+8):
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,data[i])
|
||||
shiftOut(dataPin,clockPin,MSBFIRST,~x)
|
||||
GPIO.output(latchPin,GPIO.HIGH)
|
||||
time.sleep(0.001)
|
||||
x>>=1
|
||||
def destroy():
|
||||
GPIO.cleanup()
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...' )
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
from time import sleep
|
||||
|
||||
|
||||
class Adafruit_CharLCD(object):
|
||||
|
||||
# commands
|
||||
LCD_CLEARDISPLAY = 0x01
|
||||
LCD_RETURNHOME = 0x02
|
||||
LCD_ENTRYMODESET = 0x04
|
||||
LCD_DISPLAYCONTROL = 0x08
|
||||
LCD_CURSORSHIFT = 0x10
|
||||
LCD_FUNCTIONSET = 0x20
|
||||
LCD_SETCGRAMADDR = 0x40
|
||||
LCD_SETDDRAMADDR = 0x80
|
||||
|
||||
# flags for display entry mode
|
||||
LCD_ENTRYRIGHT = 0x00
|
||||
LCD_ENTRYLEFT = 0x02
|
||||
LCD_ENTRYSHIFTINCREMENT = 0x01
|
||||
LCD_ENTRYSHIFTDECREMENT = 0x00
|
||||
|
||||
# flags for display on/off control
|
||||
LCD_DISPLAYON = 0x04
|
||||
LCD_DISPLAYOFF = 0x00
|
||||
LCD_CURSORON = 0x02
|
||||
LCD_CURSOROFF = 0x00
|
||||
LCD_BLINKON = 0x01
|
||||
LCD_BLINKOFF = 0x00
|
||||
|
||||
# flags for display/cursor shift
|
||||
LCD_DISPLAYMOVE = 0x08
|
||||
LCD_CURSORMOVE = 0x00
|
||||
|
||||
# flags for display/cursor shift
|
||||
LCD_DISPLAYMOVE = 0x08
|
||||
LCD_CURSORMOVE = 0x00
|
||||
LCD_MOVERIGHT = 0x04
|
||||
LCD_MOVELEFT = 0x00
|
||||
|
||||
# flags for function set
|
||||
LCD_8BITMODE = 0x10
|
||||
LCD_4BITMODE = 0x00
|
||||
LCD_2LINE = 0x08
|
||||
LCD_1LINE = 0x00
|
||||
LCD_5x10DOTS = 0x04
|
||||
LCD_5x8DOTS = 0x00
|
||||
|
||||
def __init__(self, pin_rs=25, pin_e=24, pins_db=[23, 17, 21, 22], GPIO=None):
|
||||
# Emulate the old behavior of using RPi.GPIO if we haven't been given
|
||||
# an explicit GPIO interface to use
|
||||
if not GPIO:
|
||||
import RPi.GPIO as GPIO
|
||||
GPIO.setwarnings(False)
|
||||
self.GPIO = GPIO
|
||||
self.pin_rs = pin_rs
|
||||
self.pin_e = pin_e
|
||||
self.pins_db = pins_db
|
||||
|
||||
self.GPIO.setmode(GPIO.BCM) #GPIO=None use Raspi PIN in BCM mode
|
||||
self.GPIO.setup(self.pin_e, GPIO.OUT)
|
||||
self.GPIO.setup(self.pin_rs, GPIO.OUT)
|
||||
|
||||
for pin in self.pins_db:
|
||||
self.GPIO.setup(pin, GPIO.OUT)
|
||||
|
||||
self.write4bits(0x33) # initialization
|
||||
self.write4bits(0x32) # initialization
|
||||
self.write4bits(0x28) # 2 line 5x7 matrix
|
||||
self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
|
||||
self.write4bits(0x06) # shift cursor right
|
||||
|
||||
self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
|
||||
|
||||
self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
|
||||
self.displayfunction |= self.LCD_2LINE
|
||||
|
||||
# Initialize to default text direction (for romance languages)
|
||||
self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
|
||||
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode
|
||||
|
||||
self.clear()
|
||||
|
||||
def begin(self, cols, lines):
|
||||
if (lines > 1):
|
||||
self.numlines = lines
|
||||
self.displayfunction |= self.LCD_2LINE
|
||||
|
||||
def home(self):
|
||||
self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
|
||||
self.delayMicroseconds(3000) # this command takes a long time!
|
||||
|
||||
def clear(self):
|
||||
self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
|
||||
self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time
|
||||
|
||||
def setCursor(self, col, row):
|
||||
self.row_offsets = [0x00, 0x40, 0x14, 0x54]
|
||||
if row > self.numlines:
|
||||
row = self.numlines - 1 # we count rows starting w/0
|
||||
self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
|
||||
|
||||
def noDisplay(self):
|
||||
""" Turn the display off (quickly) """
|
||||
self.displaycontrol &= ~self.LCD_DISPLAYON
|
||||
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
|
||||
|
||||
def display(self):
|
||||
""" Turn the display on (quickly) """
|
||||
self.displaycontrol |= self.LCD_DISPLAYON
|
||||
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
|
||||
|
||||
def noCursor(self):
|
||||
""" Turns the underline cursor off """
|
||||
self.displaycontrol &= ~self.LCD_CURSORON
|
||||
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
|
||||
|
||||
def cursor(self):
|
||||
""" Turns the underline cursor on """
|
||||
self.displaycontrol |= self.LCD_CURSORON
|
||||
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
|
||||
|
||||
def noBlink(self):
|
||||
""" Turn the blinking cursor off """
|
||||
self.displaycontrol &= ~self.LCD_BLINKON
|
||||
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
|
||||
|
||||
def blink(self):
|
||||
""" Turn the blinking cursor on """
|
||||
self.displaycontrol |= self.LCD_BLINKON
|
||||
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
|
||||
|
||||
def DisplayLeft(self):
|
||||
""" These commands scroll the display without changing the RAM """
|
||||
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
|
||||
|
||||
def scrollDisplayRight(self):
|
||||
""" These commands scroll the display without changing the RAM """
|
||||
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT)
|
||||
|
||||
def leftToRight(self):
|
||||
""" This is for text that flows Left to Right """
|
||||
self.displaymode |= self.LCD_ENTRYLEFT
|
||||
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
|
||||
|
||||
def rightToLeft(self):
|
||||
""" This is for text that flows Right to Left """
|
||||
self.displaymode &= ~self.LCD_ENTRYLEFT
|
||||
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
|
||||
|
||||
def autoscroll(self):
|
||||
""" This will 'right justify' text from the cursor """
|
||||
self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
|
||||
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
|
||||
|
||||
def noAutoscroll(self):
|
||||
""" This will 'left justify' text from the cursor """
|
||||
self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
|
||||
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
|
||||
|
||||
def write4bits(self, bits, char_mode=False):
|
||||
""" Send command to LCD """
|
||||
self.delayMicroseconds(1000) # 1000 microsecond sleep
|
||||
bits = bin(bits)[2:].zfill(8)
|
||||
self.GPIO.output(self.pin_rs, char_mode)
|
||||
for pin in self.pins_db:
|
||||
self.GPIO.output(pin, False)
|
||||
for i in range(4):
|
||||
if bits[i] == "1":
|
||||
self.GPIO.output(self.pins_db[::-1][i], True)
|
||||
self.pulseEnable()
|
||||
for pin in self.pins_db:
|
||||
self.GPIO.output(pin, False)
|
||||
for i in range(4, 8):
|
||||
if bits[i] == "1":
|
||||
self.GPIO.output(self.pins_db[::-1][i-4], True)
|
||||
self.pulseEnable()
|
||||
|
||||
def delayMicroseconds(self, microseconds):
|
||||
seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds
|
||||
sleep(seconds)
|
||||
|
||||
def pulseEnable(self):
|
||||
self.GPIO.output(self.pin_e, False)
|
||||
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
|
||||
self.GPIO.output(self.pin_e, True)
|
||||
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
|
||||
self.GPIO.output(self.pin_e, False)
|
||||
self.delayMicroseconds(1) # commands need > 37us to settle
|
||||
|
||||
def message(self, text):
|
||||
""" Send string to LCD. Newline wraps to second line"""
|
||||
for char in text:
|
||||
if char == '\n':
|
||||
self.write4bits(0xC0) # next line
|
||||
else:
|
||||
self.write4bits(ord(char), True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lcd = Adafruit_CharLCD()
|
||||
lcd.clear()
|
||||
lcd.message(" Adafruit 16x2\n Standard LCD")
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : I2CLCD1602.py
|
||||
# Description : Use the LCD display data
|
||||
# Author : freenove
|
||||
# modification: 2018/08/03
|
||||
########################################################################
|
||||
from PCF8574 import PCF8574_GPIO
|
||||
from Adafruit_LCD1602 import Adafruit_CharLCD
|
||||
|
||||
from time import sleep, strftime
|
||||
from datetime import datetime
|
||||
|
||||
def get_cpu_temp(): # get CPU temperature from file "/sys/class/thermal/thermal_zone0/temp"
|
||||
tmp = open('/sys/class/thermal/thermal_zone0/temp')
|
||||
cpu = tmp.read()
|
||||
tmp.close()
|
||||
return '{:.2f}'.format( float(cpu)/1000 ) + ' C'
|
||||
|
||||
def get_time_now(): # get system time
|
||||
return datetime.now().strftime(' %H:%M:%S')
|
||||
|
||||
def loop():
|
||||
mcp.output(3,1) # turn on LCD backlight
|
||||
lcd.begin(16,2) # set number of LCD lines and columns
|
||||
while(True):
|
||||
#lcd.clear()
|
||||
lcd.setCursor(0,0) # set cursor position
|
||||
lcd.message( 'CPU: ' + get_cpu_temp()+'\n' )# display CPU temperature
|
||||
lcd.message( get_time_now() ) # display the time
|
||||
sleep(1)
|
||||
|
||||
def destroy():
|
||||
lcd.clear()
|
||||
|
||||
PCF8574_address = 0x27 # I2C address of the PCF8574 chip.
|
||||
PCF8574A_address = 0x3F # I2C address of the PCF8574A chip.
|
||||
# Create PCF8574 GPIO adapter.
|
||||
try:
|
||||
mcp = PCF8574_GPIO(PCF8574_address)
|
||||
except:
|
||||
try:
|
||||
mcp = PCF8574_GPIO(PCF8574A_address)
|
||||
except:
|
||||
print ('I2C Address Error !')
|
||||
exit(1)
|
||||
# Create LCD, passing in MCP GPIO adapter.
|
||||
lcd = Adafruit_CharLCD(pin_rs=0, pin_e=2, pins_db=[4,5,6,7], GPIO=mcp)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('Program is starting ... ')
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt:
|
||||
destroy()
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
########################################################################
|
||||
# Filename : PCF8574.py
|
||||
# Description : PCF8574 as Raspberry GPIO
|
||||
# Author : freenove
|
||||
# modification: 2018/08/03
|
||||
########################################################################
|
||||
import smbus
|
||||
import time
|
||||
class PCF8574_I2C(object):
|
||||
OUPUT = 0
|
||||
INPUT = 1
|
||||
|
||||
def __init__(self,address):
|
||||
# Note you need to change the bus number to 0 if running on a revision 1 Raspberry Pi.
|
||||
self.bus = smbus.SMBus(1)
|
||||
self.address = address
|
||||
self.currentValue = 0
|
||||
self.writeByte(0) #I2C test.
|
||||
|
||||
def readByte(self):#Read PCF8574 all port of the data
|
||||
#value = self.bus.read_byte(self.address)
|
||||
return self.currentValue#value
|
||||
|
||||
def writeByte(self,value):#Write data to PCF8574 port
|
||||
self.currentValue = value
|
||||
self.bus.write_byte(self.address,value)
|
||||
|
||||
def digitalRead(self,pin):#Read PCF8574 one port of the data
|
||||
value = readByte()
|
||||
return (value&(1<<pin)==(1<<pin)) and 1 or 0
|
||||
|
||||
def digitalWrite(self,pin,newvalue):#Write data to PCF8574 one port
|
||||
value = self.currentValue #bus.read_byte(address)
|
||||
if(newvalue == 1):
|
||||
value |= (1<<pin)
|
||||
elif (newvalue == 0):
|
||||
value &= ~(1<<pin)
|
||||
self.writeByte(value)
|
||||
|
||||
def loop():
|
||||
mcp = PCF8574_I2C(0x27)
|
||||
while True:
|
||||
#mcp.writeByte(0xff)
|
||||
mcp.digitalWrite(3,1)
|
||||
print ('Is 0xff? %x'%(mcp.readByte()))
|
||||
time.sleep(1)
|
||||
mcp.writeByte(0x00)
|
||||
#mcp.digitalWrite(7,1)
|
||||
print ('Is 0x00? %x'%(mcp.readByte()))
|
||||
time.sleep(1)
|
||||
|
||||
class PCF8574_GPIO(object):#Standardization function interface
|
||||
OUT = 0
|
||||
IN = 1
|
||||
BCM = 0
|
||||
BOARD = 0
|
||||
def __init__(self,address):
|
||||
self.chip = PCF8574_I2C(address)
|
||||
self.address = address
|
||||
def setmode(self,mode):#PCF8574 port belongs to two-way IO, do not need to set the input and output model
|
||||
pass
|
||||
def setup(self,pin,mode):
|
||||
pass
|
||||
def input(self,pin):#Read PCF8574 one port of the data
|
||||
return self.chip.digitalRead(pin)
|
||||
def output(self,pin,value):#Write data to PCF8574 one port
|
||||
self.chip.digitalWrite(pin,value)
|
||||
|
||||
def destroy():
|
||||
bus.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('Program is starting ... ')
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt:
|
||||
destroy()
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : DHT11.py
|
||||
# Description : read the temperature and humidity data of DHT11
|
||||
# Author : freenove
|
||||
# modification: 2020/10/16
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import Freenove_DHT as DHT
|
||||
DHTPin = 11 #define the pin of DHT11
|
||||
|
||||
def loop():
|
||||
dht = DHT.DHT(DHTPin) #create a DHT class object
|
||||
counts = 0 # Measurement counts
|
||||
while(True):
|
||||
counts += 1
|
||||
print("Measurement counts: ", counts)
|
||||
for i in range(0,15):
|
||||
chk = dht.readDHT11() #read DHT11 and get a return value. Then determine whether data read is normal according to the return value.
|
||||
if (chk is dht.DHTLIB_OK): #read DHT11 and get a return value. Then determine whether data read is normal according to the return value.
|
||||
print("DHT11,OK!")
|
||||
break
|
||||
time.sleep(0.1)
|
||||
print("Humidity : %.2f, \t Temperature : %.2f \n"%(dht.humidity,dht.temperature))
|
||||
time.sleep(2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('Program is starting ... ')
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt:
|
||||
GPIO.cleanup()
|
||||
exit()
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : Freenove_DHT.py
|
||||
# Description : DHT Temperature & Humidity Sensor library for Raspberry
|
||||
# Author : freenove
|
||||
# modification: 2020/10/16
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
class DHT(object):
|
||||
DHTLIB_OK = 0
|
||||
DHTLIB_ERROR_CHECKSUM = -1
|
||||
DHTLIB_ERROR_TIMEOUT = -2
|
||||
DHTLIB_INVALID_VALUE = -999
|
||||
|
||||
DHTLIB_DHT11_WAKEUP = 0.020#0.018 #18ms
|
||||
DHTLIB_TIMEOUT = 0.0001 #100us
|
||||
|
||||
humidity = 0
|
||||
temperature = 0
|
||||
|
||||
def __init__(self,pin):
|
||||
self.pin = pin
|
||||
self.bits = [0,0,0,0,0]
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
#Read DHT sensor, store the original data in bits[]
|
||||
def readSensor(self,pin,wakeupDelay):
|
||||
mask = 0x80
|
||||
idx = 0
|
||||
self.bits = [0,0,0,0,0]
|
||||
# Clear sda
|
||||
GPIO.setup(pin,GPIO.OUT)
|
||||
GPIO.output(pin,GPIO.HIGH)
|
||||
time.sleep(0.5)
|
||||
# start signal
|
||||
GPIO.output(pin,GPIO.LOW)
|
||||
time.sleep(wakeupDelay)
|
||||
GPIO.output(pin,GPIO.HIGH)
|
||||
# time.sleep(0.000001)
|
||||
GPIO.setup(pin,GPIO.IN)
|
||||
|
||||
loopCnt = self.DHTLIB_TIMEOUT
|
||||
# Waiting echo
|
||||
t = time.time()
|
||||
while True:
|
||||
if (GPIO.input(pin) == GPIO.LOW):
|
||||
break
|
||||
if((time.time() - t) > loopCnt):
|
||||
return self.DHTLIB_ERROR_TIMEOUT
|
||||
# Waiting echo low level end
|
||||
t = time.time()
|
||||
while(GPIO.input(pin) == GPIO.LOW):
|
||||
if((time.time() - t) > loopCnt):
|
||||
#print ("Echo LOW")
|
||||
return self.DHTLIB_ERROR_TIMEOUT
|
||||
# Waiting echo high level end
|
||||
t = time.time()
|
||||
while(GPIO.input(pin) == GPIO.HIGH):
|
||||
if((time.time() - t) > loopCnt):
|
||||
#print ("Echo HIGH")
|
||||
return self.DHTLIB_ERROR_TIMEOUT
|
||||
for i in range(0,40,1):
|
||||
t = time.time()
|
||||
while(GPIO.input(pin) == GPIO.LOW):
|
||||
if((time.time() - t) > loopCnt):
|
||||
#print ("Data Low %d"%(i))
|
||||
return self.DHTLIB_ERROR_TIMEOUT
|
||||
t = time.time()
|
||||
while(GPIO.input(pin) == GPIO.HIGH):
|
||||
if((time.time() - t) > loopCnt):
|
||||
#print ("Data HIGH %d"%(i))
|
||||
return self.DHTLIB_ERROR_TIMEOUT
|
||||
if((time.time() - t) > 0.00005):
|
||||
self.bits[idx] |= mask
|
||||
#print("t : %f"%(time.time()-t))
|
||||
mask >>= 1
|
||||
if(mask == 0):
|
||||
mask = 0x80
|
||||
idx += 1
|
||||
#print (self.bits)
|
||||
GPIO.setup(pin,GPIO.OUT)
|
||||
GPIO.output(pin,GPIO.HIGH)
|
||||
return self.DHTLIB_OK
|
||||
#Read DHT sensor, analyze the data of temperature and humidity
|
||||
def readDHT11Once(self):
|
||||
rv = self.readSensor(self.pin,self.DHTLIB_DHT11_WAKEUP)
|
||||
if (rv is not self.DHTLIB_OK):
|
||||
self.humidity = self.DHTLIB_INVALID_VALUE
|
||||
self.temperature = self.DHTLIB_INVALID_VALUE
|
||||
return rv
|
||||
self.humidity = self.bits[0]
|
||||
self.temperature = self.bits[2] + self.bits[3]*0.1
|
||||
sumChk = ((self.bits[0] + self.bits[1] + self.bits[2] + self.bits[3]) & 0xFF)
|
||||
if(self.bits[4] is not sumChk):
|
||||
return self.DHTLIB_ERROR_CHECKSUM
|
||||
return self.DHTLIB_OK
|
||||
def readDHT11(self):
|
||||
result = self.DHTLIB_INVALID_VALUE
|
||||
for i in range(0,15):
|
||||
result = self.readDHT11Once()
|
||||
if result == self.DHTLIB_OK:
|
||||
return self.DHTLIB_OK
|
||||
time.sleep(0.1)
|
||||
return result
|
||||
|
||||
|
||||
def loop():
|
||||
dht = DHT(11)
|
||||
sumCnt = 0
|
||||
okCnt = 0
|
||||
while(True):
|
||||
sumCnt += 1
|
||||
chk = dht.readDHT11()
|
||||
if (chk is 0):
|
||||
okCnt += 1
|
||||
okRate = 100.0*okCnt/sumCnt;
|
||||
print("sumCnt : %d, \t okRate : %.2f%% "%(sumCnt,okRate))
|
||||
print("chk : %d, \t Humidity : %.2f, \t Temperature : %.2f "%(chk,dht.humidity,dht.temperature))
|
||||
time.sleep(3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('Program is starting ... ')
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
exit()
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
from setuptools import setup,find_packages
|
||||
|
||||
setup(
|
||||
name = "Freenove_DHT",
|
||||
version = "V1.0.1",
|
||||
description = "Read DHT Sensor",
|
||||
author = "Freenove",
|
||||
url = "http://www.freenove.com",
|
||||
license = " ",
|
||||
packages = find_packages(),
|
||||
scripts = ["Freenove_DHT.py"],
|
||||
)
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : Keypad.py
|
||||
# Description : The module of matrix keypad
|
||||
# Author : freenove
|
||||
# modification: 2016/07/13
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
#class Key:Define some of the properties of Key
|
||||
class Key(object):
|
||||
NO_KEY = '\0'
|
||||
#Defines the four states of Key
|
||||
IDLE = 0
|
||||
PRESSED = 1
|
||||
HOLD = 2
|
||||
RELEASED = 3
|
||||
#define OPEN and CLOSED
|
||||
OPEN = 0
|
||||
CLOSED =1
|
||||
#constructor
|
||||
def __init__(self):
|
||||
self.kchar = self.NO_KEY
|
||||
self.kstate = self.IDLE
|
||||
self.kcode = -1
|
||||
self.stateChanged = False
|
||||
|
||||
class Keypad(object):
|
||||
NULL = '\0'
|
||||
LIST_MAX = 10 #Max number of keys on the active list.
|
||||
MAPSIZE = 10 #MAPSIZE is the number of rows (times 16 columns)
|
||||
bitMap = [0]*MAPSIZE
|
||||
key = [Key()]*LIST_MAX
|
||||
holdTime = 500 #key hold time
|
||||
holdTimer = 0
|
||||
startTime = 0
|
||||
#Allows custom keymap, pin configuration, and keypad sizes.
|
||||
def __init__(self,usrKeyMap,row_Pins,col_Pins,num_Rows,num_Cols):
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
self.rowPins = row_Pins
|
||||
self.colPins = col_Pins
|
||||
self.numRows = num_Rows
|
||||
self.numCols = num_Cols
|
||||
|
||||
self.keymap = usrKeyMap
|
||||
self.setDebounceTime(10)
|
||||
#Returns a single key only. Retained for backwards compatibility.
|
||||
def getKey(self):
|
||||
single_key = True
|
||||
if(self.getKeys() and self.key[0].stateChanged and (self.key[0].kstate == self.key[0].PRESSED)):
|
||||
return self.key[0].kchar
|
||||
single_key = False
|
||||
return self.key[0].NO_KEY
|
||||
#Populate the key list.
|
||||
def getKeys(self):
|
||||
keyActivity = False
|
||||
#Limit how often the keypad is scanned.
|
||||
if((time.time() - self.startTime) > self.debounceTime*0.001):
|
||||
self.scanKeys()
|
||||
keyActivity = self.updateList()
|
||||
self.startTime = time.time()
|
||||
return keyActivity
|
||||
#Hardware scan ,the result store in bitMap
|
||||
def scanKeys(self):
|
||||
#Re-intialize the row pins. Allows sharing these pins with other hardware.
|
||||
for pin_r in self.rowPins:
|
||||
GPIO.setup(pin_r,GPIO.IN,pull_up_down = GPIO.PUD_UP)
|
||||
#bitMap stores ALL the keys that are being pressed.
|
||||
for pin_c in self.colPins:
|
||||
GPIO.setup(pin_c,GPIO.OUT)
|
||||
GPIO.output(pin_c,GPIO.LOW)
|
||||
for r in self.rowPins: #keypress is active low so invert to high.
|
||||
self.bitMap[self.rowPins.index(r)] = self.bitWrite(self.bitMap[self.rowPins.index(r)],self.colPins.index(pin_c),not GPIO.input(r))
|
||||
#Set pin to high impedance input. Effectively ends column pulse.
|
||||
GPIO.output(pin_c,GPIO.HIGH)
|
||||
GPIO.setup(pin_c,GPIO.IN)
|
||||
#Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
|
||||
def updateList(self):
|
||||
anyActivity = False
|
||||
kk = Key()
|
||||
#Delete any IDLE keys
|
||||
for i in range(self.LIST_MAX):
|
||||
if(self.key[i].kstate == kk.IDLE):
|
||||
self.key[i].kchar = kk.NO_KEY
|
||||
self.key[i].kcode = -1
|
||||
self.key[i].stateChanged = False
|
||||
# Add new keys to empty slots in the key list.
|
||||
for r in range(self.numRows):
|
||||
for c in range(self.numCols):
|
||||
button = self.bitRead(self.bitMap[r],c)
|
||||
keyChar = self.keymap[r * self.numCols +c]
|
||||
keyCode = r * self.numCols +c
|
||||
idx = self.findInList(keyCode)
|
||||
#Key is already on the list so set its next state.
|
||||
if(idx > -1):
|
||||
self.nextKeyState(idx,button)
|
||||
#Key is NOT on the list so add it.
|
||||
if((idx == -1) and button):
|
||||
for i in range(self.LIST_MAX):
|
||||
if(self.key[i].kchar == kk.NO_KEY): #Find an empty slot or don't add key to list.
|
||||
self.key[i].kchar = keyChar
|
||||
self.key[i].kcode = keyCode
|
||||
self.key[i].kstate = kk.IDLE #Keys NOT on the list have an initial state of IDLE.
|
||||
self.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 i in range(self.LIST_MAX):
|
||||
if(self.key[i].stateChanged):
|
||||
anyActivity = True
|
||||
return anyActivity
|
||||
#This function is a state machine but is also used for debouncing the keys.
|
||||
def nextKeyState(self,idx, button):
|
||||
self.key[idx].stateChanged = False
|
||||
kk = Key()
|
||||
if(self.key[idx].kstate == kk.IDLE):
|
||||
if(button == kk.CLOSED):
|
||||
self.transitionTo(idx,kk.PRESSED)
|
||||
self.holdTimer = time.time() #Get ready for next HOLD state.
|
||||
elif(self.key[idx].kstate == kk.PRESSED):
|
||||
if((time.time() - self.holdTimer) > self.holdTime*0.001): #Waiting for a key HOLD...
|
||||
self.transitionTo(idx,kk.HOLD)
|
||||
elif(button == kk.OPEN): # or for a key to be RELEASED.
|
||||
self.transitionTo(idx,kk.RELEASED)
|
||||
elif(self.key[idx].kstate == kk.HOLD):
|
||||
if(button == kk.OPEN):
|
||||
self.transitionTo(idx,kk.RELEASED)
|
||||
elif(self.key[idx].kstate == kk.RELEASED):
|
||||
self.transitionTo(idx,kk.IDLE)
|
||||
|
||||
def transitionTo(self,idx,nextState):
|
||||
self.key[idx].kstate = nextState
|
||||
self.key[idx].stateChanged = True
|
||||
#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.
|
||||
def findInList(self,keyCode):
|
||||
for i in range(self.LIST_MAX):
|
||||
if(self.key[i].kcode == keyCode):
|
||||
return i
|
||||
return -1
|
||||
#set Debounce Time, The default is 50ms
|
||||
def setDebounceTime(self,ms):
|
||||
self.debounceTime = ms
|
||||
#set HoldTime,The default is 500ms
|
||||
def setHoldTime(self,ms):
|
||||
self.holdTime = ms
|
||||
#
|
||||
def isPressed(keyChar):
|
||||
for i in range(self.LIST_MAX):
|
||||
if(self.key[i].kchar == keyChar):
|
||||
if(self.key[i].kstate == self.self.key[i].PRESSED and self.key[i].stateChanged):
|
||||
return True
|
||||
return False
|
||||
#
|
||||
def waitForKey():
|
||||
kk = Key()
|
||||
waitKey = kk.NO_KEY
|
||||
while(waitKey == kk.NO_KEY):
|
||||
waitKey = getKey()
|
||||
return waitKey
|
||||
|
||||
def getState():
|
||||
return self.key[0].kstate
|
||||
#
|
||||
def keyStateChanged():
|
||||
return self.key[0].stateChanged
|
||||
|
||||
def bitWrite(self,x,n,b):
|
||||
if(b):
|
||||
x |= (1<<n)
|
||||
else:
|
||||
x &=(~(1<<n))
|
||||
return x
|
||||
def bitRead(self,x,n):
|
||||
if((x>>n)&1 == 1):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
#######################EXAMPLE##################################
|
||||
ROWS = 4
|
||||
COLS = 4
|
||||
keys = [ '1','2','3','A',
|
||||
'4','5','6','B',
|
||||
'7','8','9','C',
|
||||
'*','0','#','D' ]
|
||||
rowsPins = [12,16,18,22]
|
||||
colsPins = [19,15,13,11]
|
||||
|
||||
def loop():
|
||||
keypad = Keypad(keys,rowsPins,colsPins,ROWS,COLS)
|
||||
keypad.setDebounceTime(50)
|
||||
while(True):
|
||||
key = keypad.getKey()
|
||||
if(key != keypad.NULL):
|
||||
print ("You Pressed Key : %c "%(key) )
|
||||
|
||||
if __name__ == '__main__': # Program start from here
|
||||
print ("Program is starting ... ")
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
|
||||
pass
|
||||
GPIO.cleanup()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : MatrixKeypad.py
|
||||
# Description : obtain the key code of 4x4 Matrix Keypad
|
||||
# Author : freenove
|
||||
# modification: 2018/08/03
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import Keypad #import module Keypad
|
||||
ROWS = 4 # number of rows of the Keypad
|
||||
COLS = 4 #number of columns of the Keypad
|
||||
keys = [ '1','2','3','A', #key code
|
||||
'4','5','6','B',
|
||||
'7','8','9','C',
|
||||
'*','0','#','D' ]
|
||||
rowsPins = [12,16,18,22] #connect to the row pinouts of the keypad
|
||||
colsPins = [19,15,13,11] #connect to the column pinouts of the keypad
|
||||
|
||||
def loop():
|
||||
keypad = Keypad.Keypad(keys,rowsPins,colsPins,ROWS,COLS) #creat Keypad object
|
||||
keypad.setDebounceTime(50) #set the debounce time
|
||||
while(True):
|
||||
key = keypad.getKey() #obtain the state of keys
|
||||
if(key != keypad.NULL): #if there is key pressed, print its key code.
|
||||
print ("You Pressed Key : %c "%(key))
|
||||
|
||||
if __name__ == '__main__': #Program start from here
|
||||
print ("Program is starting ... ")
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: #When 'Ctrl+C' is pressed, exit the program.
|
||||
GPIO.cleanup()
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : SenseLED.py
|
||||
# Description : Control led with infrared Motion sensor.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
ledPin = 12 # define ledPin
|
||||
sensorPin = 11 # define sensorPin
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(ledPin, GPIO.OUT) # set ledPin to OUTPUT mode
|
||||
GPIO.setup(sensorPin, GPIO.IN) # set sensorPin to INPUT mode
|
||||
|
||||
def loop():
|
||||
while True:
|
||||
if GPIO.input(sensorPin)==GPIO.HIGH:
|
||||
GPIO.output(ledPin,GPIO.HIGH) # turn on led
|
||||
print ('led turned on >>>')
|
||||
else :
|
||||
GPIO.output(ledPin,GPIO.LOW) # turn off led
|
||||
print ('led turned off <<<')
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup() # Release GPIO resource
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : UltrasonicRanging.py
|
||||
# Description : Get distance via UltrasonicRanging sensor
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
trigPin = 16
|
||||
echoPin = 18
|
||||
MAX_DISTANCE = 220 # define the maximum measuring distance, unit: cm
|
||||
timeOut = MAX_DISTANCE*60 # calculate timeout according to the maximum measuring distance
|
||||
|
||||
def pulseIn(pin,level,timeOut): # obtain pulse time of a pin under timeOut
|
||||
t0 = time.time()
|
||||
while(GPIO.input(pin) != level):
|
||||
if((time.time() - t0) > timeOut*0.000001):
|
||||
return 0;
|
||||
t0 = time.time()
|
||||
while(GPIO.input(pin) == level):
|
||||
if((time.time() - t0) > timeOut*0.000001):
|
||||
return 0;
|
||||
pulseTime = (time.time() - t0)*1000000
|
||||
return pulseTime
|
||||
|
||||
def getSonar(): # get the measurement results of ultrasonic module,with unit: cm
|
||||
GPIO.output(trigPin,GPIO.HIGH) # make trigPin output 10us HIGH level
|
||||
time.sleep(0.00001) # 10us
|
||||
GPIO.output(trigPin,GPIO.LOW) # make trigPin output LOW level
|
||||
pingTime = pulseIn(echoPin,GPIO.HIGH,timeOut) # read plus time of echoPin
|
||||
distance = pingTime * 340.0 / 2.0 / 10000.0 # calculate distance with sound speed 340m/s
|
||||
return distance
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(trigPin, GPIO.OUT) # set trigPin to OUTPUT mode
|
||||
GPIO.setup(echoPin, GPIO.IN) # set echoPin to INPUT mode
|
||||
|
||||
def loop():
|
||||
while(True):
|
||||
distance = getSonar() # get distance
|
||||
print ("The distance is : %.2f cm"%(distance))
|
||||
time.sleep(1)
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
GPIO.cleanup() # release GPIO resource
|
||||
|
||||
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
MPU6050 Python I2C Class
|
||||
|
||||
Copyright (c) 2015 Geir Istad
|
||||
|
||||
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.
|
||||
|
||||
+946
@@ -0,0 +1,946 @@
|
||||
__author__ = 'Geir Istad'
|
||||
"""
|
||||
MPU6050 Python I2C Class
|
||||
Copyright (c) 2015 Geir Istad
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Code based on
|
||||
I2Cdev library collection - MPU6050 I2C device class
|
||||
by Jeff Rowberg <[email protected]>
|
||||
============================================
|
||||
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.
|
||||
===============================================
|
||||
"""
|
||||
|
||||
import math
|
||||
import ctypes
|
||||
import time
|
||||
import smbus
|
||||
import csv
|
||||
from MPUConstants import MPUConstants as C
|
||||
from Quaternion import Quaternion as Q
|
||||
from Quaternion import XYZVector as V
|
||||
|
||||
|
||||
class MPU6050:
|
||||
__buffer = [0] * 14
|
||||
__debug = False
|
||||
__DMP_packet_size = 0
|
||||
__dev_id = 0
|
||||
__bus = None
|
||||
|
||||
def __init__(self, a_bus=1, a_address=C.MPU6050_DEFAULT_ADDRESS,
|
||||
a_xAOff=None, a_yAOff=None, a_zAOff=None, a_xGOff=None,
|
||||
a_yGOff=None, a_zGOff=None, a_debug=False):
|
||||
self.__dev_id = a_address
|
||||
# Connect to num 1 SMBus
|
||||
self.__bus = smbus.SMBus(a_bus)
|
||||
# Set clock source to gyro
|
||||
self.set_clock_source(C.MPU6050_CLOCK_PLL_XGYRO)
|
||||
# Set accelerometer range
|
||||
self.set_full_scale_accel_range(C.MPU6050_ACCEL_FS_2)
|
||||
# Set gyro range
|
||||
self.set_full_scale_gyro_range(C.MPU6050_GYRO_FS_250)
|
||||
# Take the MPU out of time.sleep mode
|
||||
self.wake_up()
|
||||
# Set offsets
|
||||
if a_xAOff:
|
||||
self.set_x_accel_offset(a_xAOff)
|
||||
if a_yAOff:
|
||||
self.set_y_accel_offset(a_yAOff)
|
||||
if a_zAOff:
|
||||
self.set_z_accel_offset(a_zAOff)
|
||||
if a_xGOff:
|
||||
self.set_x_gyro_offset(a_xGOff)
|
||||
if a_yGOff:
|
||||
self.set_y_gyro_offset(a_yGOff)
|
||||
if a_zGOff:
|
||||
self.set_z_gyro_offset(a_zGOff)
|
||||
self.__debug = a_debug
|
||||
|
||||
# Core bit and byte operations
|
||||
def read_bit(self, a_reg_add, a_bit_position):
|
||||
return self.read_bits(a_reg_add, a_bit_position, 1)
|
||||
|
||||
def write_bit(self, a_reg_add, a_bit_num, a_bit):
|
||||
byte = self.__bus.read_byte_data(self.__dev_id, a_reg_add)
|
||||
if a_bit:
|
||||
byte |= 1 << a_bit_num
|
||||
else:
|
||||
byte &= ~(1 << a_bit_num)
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, a_reg_add, ctypes.c_int8(byte).value)
|
||||
|
||||
def read_bits(self, a_reg_add, a_bit_start, a_length):
|
||||
byte = self.__bus.read_byte_data(self.__dev_id, a_reg_add)
|
||||
mask = ((1 << a_length) - 1) << (a_bit_start - a_length + 1)
|
||||
byte &= mask
|
||||
byte >>= a_bit_start - a_length + 1
|
||||
return byte
|
||||
|
||||
def write_bits(self, a_reg_add, a_bit_start, a_length, a_data):
|
||||
byte = self.__bus.read_byte_data(self.__dev_id, a_reg_add)
|
||||
mask = ((1 << a_length) - 1) << (a_bit_start - a_length + 1)
|
||||
# Get data in position and zero all non-important bits in data
|
||||
a_data <<= a_bit_start - a_length + 1
|
||||
a_data &= mask
|
||||
# Clear all important bits in read byte and combine with data
|
||||
byte &= ~mask
|
||||
byte = byte | a_data
|
||||
# Write the data to the I2C device
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, a_reg_add, ctypes.c_int8(byte).value)
|
||||
|
||||
def read_memory_byte(self):
|
||||
return self.__bus.read_byte_data(self.__dev_id, C.MPU6050_RA_MEM_R_W)
|
||||
|
||||
def read_bytes(self, a_data_list, a_address, a_length):
|
||||
if a_length > len(a_data_list):
|
||||
print('read_bytes, length of passed list too short')
|
||||
return a_data_list
|
||||
# Attempt to use the built in read bytes function in the adafruit lib
|
||||
# a_data_list = self.__bus.read_i2c_block_data(self.__dev_id, a_address,
|
||||
# a_length)
|
||||
# Attempt to bypass adafruit lib
|
||||
#a_data_list = self.__mpu.bus.read_i2c_block_data(0x68, a_address, a_length)
|
||||
#print('data' + str(a_data_list))
|
||||
for x in range(0, a_length):
|
||||
a_data_list[x] = self.__bus.read_byte_data(self.__dev_id,
|
||||
a_address + x)
|
||||
return a_data_list
|
||||
|
||||
def write_memory_block(self, a_data_list, a_data_size, a_bank, a_address,
|
||||
a_verify):
|
||||
success = True
|
||||
self.set_memory_bank(a_bank)
|
||||
self.set_memory_start_address(a_address)
|
||||
|
||||
# For each a_data_item we want to write it to the board to a certain
|
||||
# memory bank and address
|
||||
for i in range(0, a_data_size):
|
||||
# Write each data to memory
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_MEM_R_W,
|
||||
a_data_list[i])
|
||||
|
||||
if a_verify:
|
||||
self.set_memory_bank(a_bank)
|
||||
self.set_memory_start_address(a_address)
|
||||
verify_data = self.__bus.read_byte_data(self.__dev_id,
|
||||
C.MPU6050_RA_MEM_R_W)
|
||||
if verify_data != a_data_list[i]:
|
||||
success = False
|
||||
|
||||
# If we've filled the bank, change the memory bank
|
||||
if a_address == 255:
|
||||
a_address = 0
|
||||
a_bank += 1
|
||||
self.set_memory_bank(a_bank)
|
||||
else:
|
||||
a_address += 1
|
||||
|
||||
# Either way update the memory address
|
||||
self.set_memory_start_address(a_address)
|
||||
|
||||
return success
|
||||
|
||||
def wake_up(self):
|
||||
self.write_bit(
|
||||
C.MPU6050_RA_PWR_MGMT_1, C.MPU6050_PWR1_SLEEP_BIT, 0)
|
||||
|
||||
def set_clock_source(self, a_source):
|
||||
self.write_bits(C.MPU6050_RA_PWR_MGMT_1, C.MPU6050_PWR1_CLKSEL_BIT,
|
||||
C.MPU6050_PWR1_CLKSEL_LENGTH, a_source)
|
||||
|
||||
def set_full_scale_gyro_range(self, a_data):
|
||||
self.write_bits(C.MPU6050_RA_GYRO_CONFIG,
|
||||
C.MPU6050_GCONFIG_FS_SEL_BIT,
|
||||
C.MPU6050_GCONFIG_FS_SEL_LENGTH, a_data)
|
||||
|
||||
def set_full_scale_accel_range(self, a_data):
|
||||
self.write_bits(C.MPU6050_RA_ACCEL_CONFIG,
|
||||
C.MPU6050_ACONFIG_AFS_SEL_BIT,
|
||||
C.MPU6050_ACONFIG_AFS_SEL_LENGTH, a_data)
|
||||
|
||||
def reset(self):
|
||||
self.write_bit(C.MPU6050_RA_PWR_MGMT_1,
|
||||
C.MPU6050_PWR1_DEVICE_RESET_BIT, 1)
|
||||
|
||||
def set_sleep_enabled(self, a_enabled):
|
||||
set_bit = 0
|
||||
if a_enabled:
|
||||
set_bit = 1
|
||||
self.write_bit(C.MPU6050_RA_PWR_MGMT_1,
|
||||
C.MPU6050_PWR1_SLEEP_BIT, set_bit)
|
||||
|
||||
def set_memory_bank(self, a_bank, a_prefetch_enabled=False,
|
||||
a_user_bank=False):
|
||||
a_bank &= 0x1F
|
||||
if a_user_bank:
|
||||
a_bank |= 0x20
|
||||
if a_prefetch_enabled:
|
||||
a_bank |= 0x20
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_BANK_SEL, a_bank)
|
||||
|
||||
def set_memory_start_address(self, a_address):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_MEM_START_ADDR, a_address)
|
||||
|
||||
def get_x_gyro_offset_TC(self):
|
||||
return self.read_bits(C.MPU6050_RA_XG_OFFS_TC,
|
||||
C.MPU6050_TC_OFFSET_BIT,
|
||||
C.MPU6050_TC_OFFSET_LENGTH)
|
||||
|
||||
def set_x_gyro_offset_TC(self, a_offset):
|
||||
self.write_bits(C.MPU6050_RA_XG_OFFS_TC,
|
||||
C.MPU6050_TC_OFFSET_BIT,
|
||||
C.MPU6050_TC_OFFSET_LENGTH, a_offset)
|
||||
|
||||
def get_y_gyro_offset_TC(self):
|
||||
return self.read_bits(C.MPU6050_RA_YG_OFFS_TC,
|
||||
C.MPU6050_TC_OFFSET_BIT,
|
||||
C.MPU6050_TC_OFFSET_LENGTH)
|
||||
|
||||
def set_y_gyro_offset_TC(self, a_offset):
|
||||
self.write_bits(C.MPU6050_RA_YG_OFFS_TC,
|
||||
C.MPU6050_TC_OFFSET_BIT,
|
||||
C.MPU6050_TC_OFFSET_LENGTH, a_offset)
|
||||
|
||||
def get_z_gyro_offset_TC(self):
|
||||
return self.read_bits(C.MPU6050_RA_ZG_OFFS_TC,
|
||||
C.MPU6050_TC_OFFSET_BIT,
|
||||
C.MPU6050_TC_OFFSET_LENGTH)
|
||||
|
||||
def set_z_gyro_offset_TC(self, a_offset):
|
||||
self.write_bits(C.MPU6050_RA_ZG_OFFS_TC,
|
||||
C.MPU6050_TC_OFFSET_BIT,
|
||||
C.MPU6050_TC_OFFSET_LENGTH, a_offset)
|
||||
|
||||
def set_slave_address(self, a_num, a_address):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_I2C_SLV0_ADDR + a_num * 3, a_address)
|
||||
|
||||
def set_I2C_master_mode_enabled(self, a_enabled):
|
||||
bit = 0
|
||||
if a_enabled:
|
||||
bit = 1
|
||||
self.write_bit(C.MPU6050_RA_USER_CTRL,
|
||||
C.MPU6050_USERCTRL_I2C_MST_EN_BIT, bit)
|
||||
|
||||
def reset_I2C_master(self):
|
||||
self.write_bit(C.MPU6050_RA_USER_CTRL,
|
||||
C.MPU6050_USERCTRL_I2C_MST_RESET_BIT, 1)
|
||||
|
||||
def write_prog_memory_block(self, a_data_list, a_data_size, a_bank=0,
|
||||
a_address=0, a_verify=True):
|
||||
return self.write_memory_block(a_data_list, a_data_size, a_bank,
|
||||
a_address, a_verify)
|
||||
|
||||
def write_DMP_configuration_set(self, a_data_list, a_data_size):
|
||||
index = 0
|
||||
while index < a_data_size:
|
||||
bank = a_data_list[index]
|
||||
offset = a_data_list[index + 1]
|
||||
length = a_data_list[index + 2]
|
||||
index += 3
|
||||
success = False
|
||||
|
||||
# Normal case
|
||||
if length > 0:
|
||||
data_selection = list()
|
||||
for subindex in range(0, length):
|
||||
data_selection.append(a_data_list[index + subindex])
|
||||
success = self.write_memory_block(data_selection, length, bank,
|
||||
offset, True)
|
||||
index += length
|
||||
# Special undocumented case
|
||||
else:
|
||||
special = a_data_list[index]
|
||||
index += 1
|
||||
if special == 0x01:
|
||||
# TODO Figure out if write8 can return True/False
|
||||
success = self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_INT_ENABLE, 0x32)
|
||||
|
||||
if success == False:
|
||||
# TODO implement error messagemajigger
|
||||
return False
|
||||
pass
|
||||
return True
|
||||
|
||||
def write_prog_dmp_configuration(self, a_data_list, a_data_size):
|
||||
return self.write_DMP_configuration_set(a_data_list, a_data_size)
|
||||
|
||||
def set_int_enable(self, a_enabled):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_INT_ENABLE, a_enabled)
|
||||
|
||||
def set_rate(self, a_rate):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_SMPLRT_DIV, a_rate)
|
||||
|
||||
def set_external_frame_sync(self, a_sync):
|
||||
self.write_bits(C.MPU6050_RA_CONFIG,
|
||||
C.MPU6050_CFG_EXT_SYNC_SET_BIT,
|
||||
C.MPU6050_CFG_EXT_SYNC_SET_LENGTH, a_sync)
|
||||
|
||||
def set_DLF_mode(self, a_mode):
|
||||
self.write_bits(C.MPU6050_RA_CONFIG, C.MPU6050_CFG_DLPF_CFG_BIT,
|
||||
C.MPU6050_CFG_DLPF_CFG_LENGTH, a_mode)
|
||||
|
||||
def get_DMP_config_1(self):
|
||||
return self.__bus.read_byte_data(self.__dev_id, C.MPU6050_RA_DMP_CFG_1)
|
||||
|
||||
def set_DMP_config_1(self, a_config):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_DMP_CFG_1, a_config)
|
||||
|
||||
def get_DMP_config_2(self):
|
||||
return self.__bus.read_byte_data(self.__dev_id, C.MPU6050_RA_DMP_CFG_2)
|
||||
|
||||
def set_DMP_config_2(self, a_config):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_DMP_CFG_2, a_config)
|
||||
|
||||
def set_OTP_bank_valid(self, a_enabled):
|
||||
bit = 0
|
||||
if a_enabled:
|
||||
bit = 1
|
||||
self.write_bit(C.MPU6050_RA_XG_OFFS_TC,
|
||||
C.MPU6050_TC_OTP_BNK_VLD_BIT, bit)
|
||||
|
||||
def get_OTP_bank_valid(self):
|
||||
return self.read_bit(C.MPU6050_RA_XG_OFFS_TC,
|
||||
C.MPU6050_TC_OTP_BNK_VLD_BIT)
|
||||
|
||||
def set_motion_detection_threshold(self, a_threshold):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_MOT_THR, a_threshold)
|
||||
|
||||
def set_zero_motion_detection_threshold(self, a_threshold):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_ZRMOT_THR, a_threshold)
|
||||
|
||||
def set_motion_detection_duration(self, a_duration):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_MOT_DUR, a_duration)
|
||||
|
||||
def set_zero_motion_detection_duration(self, a_duration):
|
||||
self.__bus.write_byte_data(
|
||||
self.__dev_id, C.MPU6050_RA_ZRMOT_DUR, a_duration)
|
||||
|
||||
def set_FIFO_enabled(self, a_enabled):
|
||||
bit = 0
|
||||
if a_enabled:
|
||||
bit = 1
|
||||
self.write_bit(C.MPU6050_RA_USER_CTRL,
|
||||
C.MPU6050_USERCTRL_FIFO_EN_BIT, bit)
|
||||
|
||||
def set_DMP_enabled(self, a_enabled):
|
||||
bit = 0
|
||||
if a_enabled:
|
||||
bit = 1
|
||||
self.write_bit(C.MPU6050_RA_USER_CTRL,
|
||||
C.MPU6050_USERCTRL_DMP_EN_BIT, bit)
|
||||
|
||||
def reset_DMP(self):
|
||||
self.write_bit(C.MPU6050_RA_USER_CTRL,
|
||||
C.MPU6050_USERCTRL_DMP_RESET_BIT, True)
|
||||
|
||||
def dmp_initialize(self):
|
||||
# Reset the MPU
|
||||
self.reset()
|
||||
# time.Sleep a bit while resetting
|
||||
time.sleep(50 / 1000)
|
||||
# Disable time.sleep mode
|
||||
self.set_sleep_enabled(0)
|
||||
|
||||
# get MPU hardware revision
|
||||
if self.__debug:
|
||||
print('Selecting user bank 16')
|
||||
self.set_memory_bank(0x10, True, True)
|
||||
|
||||
if self.__debug:
|
||||
print('Selecting memory byte 6')
|
||||
self.set_memory_start_address(0x6)
|
||||
|
||||
if self.__debug:
|
||||
print('Checking hardware revision')
|
||||
HW_revision = self.read_memory_byte()
|
||||
if self.__debug:
|
||||
print('Revision @ user[16][6] = ' + hex(HW_revision))
|
||||
|
||||
if self.__debug:
|
||||
print('Resetting memory bank selection to 0')
|
||||
self.set_memory_bank(0)
|
||||
|
||||
# check OTP bank valid
|
||||
# TODO Find out what OTP is
|
||||
OTP_valid = self.get_OTP_bank_valid()
|
||||
if self.__debug:
|
||||
if OTP_valid:
|
||||
print('OTP bank is valid')
|
||||
else:
|
||||
print('OTP bank is invalid')
|
||||
|
||||
# get X/Y/Z gyro offsets
|
||||
if self.__debug:
|
||||
print('Reading gyro offet TC values')
|
||||
x_g_offset_TC = self.get_x_gyro_offset_TC()
|
||||
y_g_offset_TC = self.get_y_gyro_offset_TC()
|
||||
z_g_offset_TC = self.get_z_gyro_offset_TC()
|
||||
if self.__debug:
|
||||
print("X gyro offset = ", repr(x_g_offset_TC))
|
||||
print("Y gyro offset = ", repr(y_g_offset_TC))
|
||||
print("Z gyro offset = ", repr(z_g_offset_TC))
|
||||
|
||||
# setup weird slave stuff (?)
|
||||
if self.__debug:
|
||||
print('Setting slave 0 address to 0x7F')
|
||||
self.set_slave_address(0, 0x7F)
|
||||
if self.__debug:
|
||||
print('Disabling I2C Master mode')
|
||||
self.set_I2C_master_mode_enabled(False)
|
||||
if self.__debug:
|
||||
print('Setting slave 0 address to 0x68 (self)')
|
||||
self.set_slave_address(0, 0x68)
|
||||
if self.__debug:
|
||||
print('Resetting I2C Master control')
|
||||
self.reset_I2C_master()
|
||||
# Wait a bit for the device to register the changes
|
||||
time.sleep(20 / 1000)
|
||||
|
||||
# load DMP code into memory banks
|
||||
if self.__debug:
|
||||
print('Writing DMP code to MPU memory banks ' +
|
||||
repr(C.MPU6050_DMP_CODE_SIZE) + ' bytes')
|
||||
if self.write_prog_memory_block(C.dmpMemory, C.MPU6050_DMP_CODE_SIZE):
|
||||
# TODO Check if we've actually verified this
|
||||
if self.__debug:
|
||||
print('Success! DMP code written and verified')
|
||||
|
||||
# Write DMP configuration
|
||||
if self.__debug:
|
||||
print('Writing DMP configuration to MPU memory banks ' +
|
||||
repr(C.MPU6050_DMP_CONFIG_SIZE) + ' bytes in config')
|
||||
if self.write_prog_dmp_configuration(C.dmpConfig,
|
||||
C.MPU6050_DMP_CONFIG_SIZE):
|
||||
if self.__debug:
|
||||
print('Success! DMP configuration written and verified.')
|
||||
print('Setting clock source to Z gyro')
|
||||
self.set_clock_source(C.MPU6050_CLOCK_PLL_ZGYRO)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting DMP and FIFO_OFLOW interrupts enabled')
|
||||
self.set_int_enable(0x12)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting sample rate to 200Hz')
|
||||
self.set_rate(4)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting external frame sync to TEMP_OUT_L[0]')
|
||||
self.set_external_frame_sync(C.MPU6050_EXT_SYNC_TEMP_OUT_L)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting DLPF bandwidth to 42Hz')
|
||||
self.set_DLF_mode(C.MPU6050_DLPF_BW_42)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting gyro sensitivity to +/- 2000 deg/sec')
|
||||
self.set_full_scale_gyro_range(C.MPU6050_GYRO_FS_2000)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting DMP configuration bytes (function unknown)')
|
||||
self.set_DMP_config_1(0x03)
|
||||
self.set_DMP_config_2(0x00)
|
||||
|
||||
if self.__debug:
|
||||
print('Clearing OTP Bank flag')
|
||||
self.set_OTP_bank_valid(False)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting X/Y/Z gyro offset TCs to previous values')
|
||||
self.set_x_gyro_offset_TC(x_g_offset_TC)
|
||||
self.set_y_gyro_offset_TC(y_g_offset_TC)
|
||||
self.set_z_gyro_offset_TC(z_g_offset_TC)
|
||||
|
||||
# Uncomment this to zero offsets when dmp_initialize is called
|
||||
# if self.__debug:
|
||||
# print('Setting X/Y/Z gyro user offsets to zero')
|
||||
# self.set_x_gyro_offset(0)
|
||||
# self.set_y_gyro_offset(0)
|
||||
# self.set_z_gyro_offset(0)
|
||||
|
||||
if self.__debug:
|
||||
print('Writing final memory update 1/7 (function unknown)')
|
||||
pos = 0
|
||||
j = 0
|
||||
dmp_update = [0] * 16
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('Writing final memory update 2/7 (function unknown)')
|
||||
j = 0
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('Resetting FIFO')
|
||||
self.reset_FIFO()
|
||||
|
||||
if self.__debug:
|
||||
print('Reading FIFO count')
|
||||
FIFO_count = self.get_FIFO_count()
|
||||
|
||||
if self.__debug:
|
||||
print('FIFO count: ' + repr(FIFO_count))
|
||||
|
||||
if self.__debug:
|
||||
print('Getting FIFO buffer')
|
||||
FIFO_buffer = [0] * 128
|
||||
FIFO_buffer = self.get_FIFO_bytes(FIFO_count)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting motion detection threshold to 2')
|
||||
self.set_motion_detection_threshold(2)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting zero-motion detection threshold to 156')
|
||||
self.set_zero_motion_detection_threshold(156)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting motion detection duration to 80')
|
||||
self.set_motion_detection_duration(80)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting zero-motion detection duration to 0')
|
||||
self.set_zero_motion_detection_duration(0)
|
||||
|
||||
if self.__debug:
|
||||
print('Resetting FIFO')
|
||||
self.reset_FIFO()
|
||||
|
||||
if self.__debug:
|
||||
print('Enabling FIFO')
|
||||
self.set_FIFO_enabled(True)
|
||||
|
||||
if self.__debug:
|
||||
print('Enabling DMP')
|
||||
self.set_DMP_enabled(True)
|
||||
|
||||
if self.__debug:
|
||||
print('Resetting DMP')
|
||||
self.reset_DMP()
|
||||
|
||||
if self.__debug:
|
||||
print('Writing final memory update 3/7 (function unknown)')
|
||||
j = 0
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('Writing final memory update 4/7 (function unknown)')
|
||||
j = 0
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('Writing final memory update 5/7 (function unknown)')
|
||||
j = 0
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('Waiting for FIFO count > 2')
|
||||
FIFO_count = self.get_FIFO_count()
|
||||
while FIFO_count < 3:
|
||||
FIFO_count = self.get_FIFO_count()
|
||||
|
||||
if self.__debug:
|
||||
print('Current FIFO count = ' + repr(FIFO_count))
|
||||
print('Reading FIFO data')
|
||||
FIFO_buffer = self.get_FIFO_bytes(FIFO_count)
|
||||
|
||||
if self.__debug:
|
||||
print('Reading interrupt status')
|
||||
MPU_int_status = self.get_int_status()
|
||||
|
||||
if self.__debug:
|
||||
print('Current interrupt status = ' + hex(MPU_int_status))
|
||||
print('Writing final memory update 6/7 (function unknown)')
|
||||
j = 0
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('Waiting for FIFO count > 2')
|
||||
FIFO_count = self.get_FIFO_count()
|
||||
while FIFO_count < 3:
|
||||
FIFO_count = self.get_FIFO_count()
|
||||
|
||||
if self.__debug:
|
||||
print('Current FIFO count = ' + repr(FIFO_count))
|
||||
print('Reading FIFO count')
|
||||
FIFO_buffer = self.get_FIFO_bytes(FIFO_count)
|
||||
|
||||
if self.__debug:
|
||||
print('Reading interrupt status')
|
||||
MPU_int_status = self.get_int_status()
|
||||
|
||||
if self.__debug:
|
||||
print('Current interrupt status = ' + hex(MPU_int_status))
|
||||
print('Writing final memory update 7/7 (function unknown)')
|
||||
j = 0
|
||||
while (j < 4) or (j < dmp_update[2] + 3):
|
||||
dmp_update[j] = C.dmpUpdates[pos]
|
||||
pos += 1
|
||||
j += 1
|
||||
# Write as block from pos 3
|
||||
self.write_memory_block(dmp_update[3:], dmp_update[2],
|
||||
dmp_update[0], dmp_update[1], True)
|
||||
|
||||
if self.__debug:
|
||||
print('DMP is good to go! Finally.')
|
||||
print('Disabling DMP (you turn it on later)')
|
||||
self.set_DMP_enabled(False)
|
||||
|
||||
if self.__debug:
|
||||
print('Setting up internal 42 byte DMP packet buffer')
|
||||
self.__DMP_packet_size = 42
|
||||
|
||||
if self.__debug:
|
||||
print(
|
||||
'Resetting FIFO and clearing INT status one last time')
|
||||
self.reset_FIFO()
|
||||
self.get_int_status()
|
||||
|
||||
else:
|
||||
if self.__debug:
|
||||
print('Configuration block loading failed')
|
||||
return 2
|
||||
|
||||
else:
|
||||
if self.__debug:
|
||||
print('Main binary block loading failed')
|
||||
return 1
|
||||
|
||||
if self.__debug:
|
||||
print('DMP initialization was successful')
|
||||
return 0
|
||||
|
||||
# Acceleration and gyro offset setters and getters
|
||||
def set_x_accel_offset(self, a_offset):
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_XA_OFFS_H,
|
||||
ctypes.c_int8(a_offset >> 8).value)
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_XA_OFFS_L_TC,
|
||||
ctypes.c_int8(a_offset).value)
|
||||
|
||||
def set_y_accel_offset(self, a_offset):
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_YA_OFFS_H,
|
||||
ctypes.c_int8(a_offset >> 8).value)
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_YA_OFFS_L_TC,
|
||||
ctypes.c_int8(a_offset).value)
|
||||
|
||||
def set_z_accel_offset(self, a_offset):
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_ZA_OFFS_H,
|
||||
ctypes.c_int8(a_offset >> 8).value)
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_ZA_OFFS_L_TC,
|
||||
ctypes.c_int8(a_offset).value)
|
||||
|
||||
def set_x_gyro_offset(self, a_offset):
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_XG_OFFS_USRH,
|
||||
ctypes.c_int8(a_offset >> 8).value)
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_XG_OFFS_USRL,
|
||||
ctypes.c_int8(a_offset).value)
|
||||
|
||||
def set_y_gyro_offset(self, a_offset):
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_YG_OFFS_USRH,
|
||||
ctypes.c_int8(a_offset >> 8).value)
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_YG_OFFS_USRL,
|
||||
ctypes.c_int8(a_offset).value)
|
||||
|
||||
def set_z_gyro_offset(self, a_offset):
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_ZG_OFFS_USRH,
|
||||
ctypes.c_int8(a_offset >> 8).value)
|
||||
self.__bus.write_byte_data(self.__dev_id, C.MPU6050_RA_ZG_OFFS_USRL,
|
||||
ctypes.c_int8(a_offset).value)
|
||||
|
||||
# Main interfacing functions to get raw data from MPU
|
||||
def get_acceleration(self):
|
||||
raw_data = self.__bus.read_i2c_block_data(self.__dev_id,
|
||||
C.MPU6050_RA_ACCEL_XOUT_H, 6)
|
||||
accel = [0] * 3
|
||||
accel[0] = ctypes.c_int16(raw_data[0] << 8 | raw_data[1]).value
|
||||
accel[1] = ctypes.c_int16(raw_data[2] << 8 | raw_data[3]).value
|
||||
accel[2] = ctypes.c_int16(raw_data[4] << 8 | raw_data[5]).value
|
||||
return accel
|
||||
|
||||
def get_rotation(self):
|
||||
raw_data = self.__bus.read_i2c_block_data(self.__dev_id,
|
||||
C.MPU6050_RA_GYRO_XOUT_H, 6)
|
||||
gyro = [0] * 3
|
||||
gyro[0] = ctypes.c_int16(raw_data[0] << 8 | raw_data[1]).value
|
||||
gyro[1] = ctypes.c_int16(raw_data[2] << 8 | raw_data[3]).value
|
||||
gyro[2] = ctypes.c_int16(raw_data[4] << 8 | raw_data[5]).value
|
||||
return gyro
|
||||
|
||||
# Interfacing functions to get data from FIFO buffer
|
||||
def DMP_get_FIFO_packet_size(self):
|
||||
return self.__DMP_packet_size
|
||||
|
||||
def reset_FIFO(self):
|
||||
self.write_bit(C.MPU6050_RA_USER_CTRL,
|
||||
C.MPU6050_USERCTRL_FIFO_RESET_BIT, True)
|
||||
|
||||
def get_FIFO_count(self):
|
||||
data = [0] * 2
|
||||
data = self.read_bytes(data, C.MPU6050_RA_FIFO_COUNTH, 2)
|
||||
return (data[0] << 8) | data[1]
|
||||
|
||||
def get_FIFO_bytes(self, a_FIFO_count):
|
||||
return_list = list()
|
||||
for index in range(0, a_FIFO_count):
|
||||
return_list.append(
|
||||
self.__bus.read_byte_data(self.__dev_id,
|
||||
C.MPU6050_RA_FIFO_R_W))
|
||||
return return_list
|
||||
|
||||
def get_int_status(self):
|
||||
return self.__bus.read_byte_data(self.__dev_id,
|
||||
C.MPU6050_RA_INT_STATUS)
|
||||
|
||||
# Data retrieval from received FIFO buffer
|
||||
def DMP_get_quaternion_int16(self, a_FIFO_buffer):
|
||||
w = ctypes.c_int16((a_FIFO_buffer[0] << 8) | a_FIFO_buffer[1]).value
|
||||
x = ctypes.c_int16((a_FIFO_buffer[4] << 8) | a_FIFO_buffer[5]).value
|
||||
y = ctypes.c_int16((a_FIFO_buffer[8] << 8) | a_FIFO_buffer[9]).value
|
||||
z = ctypes.c_int16((a_FIFO_buffer[12] << 8) | a_FIFO_buffer[13]).value
|
||||
return Q(w, x, y, z)
|
||||
|
||||
def DMP_get_quaternion(self, a_FIFO_buffer):
|
||||
quat = self.DMP_get_quaternion_int16(a_FIFO_buffer)
|
||||
w = quat.w / 16384.0
|
||||
x = quat.x / 16384.0
|
||||
y = quat.y / 16384.0
|
||||
z = quat.z / 16384.0
|
||||
return Q(w, x, y, z)
|
||||
|
||||
def DMP_get_acceleration_int16(self, a_FIFO_buffer):
|
||||
x = ctypes.c_int16(a_FIFO_buffer[28] << 8 | a_FIFO_buffer[29]).value
|
||||
y = ctypes.c_int16(a_FIFO_buffer[32] << 8 | a_FIFO_buffer[33]).value
|
||||
z = ctypes.c_int16(a_FIFO_buffer[36] << 8 | a_FIFO_buffer[37]).value
|
||||
return V(x, y, z)
|
||||
|
||||
def DMP_get_gravity(self, a_quat):
|
||||
x = 2.0 * (a_quat.x * a_quat.z - a_quat.w * a_quat.y)
|
||||
y = 2.0 * (a_quat.w * a_quat.x + a_quat.y * a_quat.z)
|
||||
z = 1.0 * (a_quat.w * a_quat.w - a_quat.x * a_quat.x -
|
||||
a_quat.y * a_quat.y + a_quat.z * a_quat.z)
|
||||
return V(x, y, z)
|
||||
|
||||
def DMP_get_linear_accel_int16(self, a_v_raw, a_grav):
|
||||
x = ctypes.c_int16(a_v_raw.x - (a_grav.x*8192)).value
|
||||
y = ctypes.c_int16(a_v_raw.y - (a_grav.y*8192)).value
|
||||
y = ctypes.c_int16(a_v_raw.y - (a_grav.y*8192)).value
|
||||
return V(x, y, z)
|
||||
|
||||
def DMP_get_euler(self, a_quat):
|
||||
psi = math.atan2(2*a_quat.x*a_quat.y - 2*a_quat.w*a_quat.z,
|
||||
2*a_quat.w*a_quat.w + 2*a_quat.x*a_quat.x - 1)
|
||||
theta = -asin(2*a_quat.x*a_quat.z + 2*a_quat.w*a_quat.y)
|
||||
phi = math.atan2(2*a_quat.y*a_quat.z - 2*a_quat.w*a_quat.x,
|
||||
2*a_quat.w*a_quat.w + 2*a_quat.z*a_quat.z - 1)
|
||||
return V(psi, theta, phi)
|
||||
|
||||
def DMP_get_roll_pitch_yaw(self, a_quat, a_grav_vect):
|
||||
# roll: (tilt left/right, about X axis)
|
||||
roll = math.atan(a_grav_vect.y /
|
||||
math.sqrt(a_grav_vect.x*a_grav_vect.x +
|
||||
a_grav_vect.z*a_grav_vect.z))
|
||||
# pitch: (nose up/down, about Y axis)
|
||||
pitch = math.atan(a_grav_vect.x /
|
||||
math.sqrt(a_grav_vect.y*a_grav_vect.y +
|
||||
a_grav_vect.z*a_grav_vect.z))
|
||||
# yaw: (about Z axis)
|
||||
yaw = math.atan2(2*a_quat.x*a_quat.y - 2*a_quat.w*a_quat.z,
|
||||
2*a_quat.w*a_quat.w + 2*a_quat.x*a_quat.x - 1)
|
||||
return V(roll, pitch, yaw)
|
||||
|
||||
def DMP_get_euler_roll_pitch_yaw(self, a_quat, a_grav_vect):
|
||||
rad_ypr = self.DMP_get_roll_pitch_yaw(a_quat, a_grav_vect)
|
||||
roll = rad_ypr.x * (180.0/math.pi)
|
||||
pitch = rad_ypr.y * (180.0/math.pi)
|
||||
yaw = rad_ypr.z * (180.0/math.pi)
|
||||
return V(roll, pitch, yaw)
|
||||
|
||||
def DMP_get_linear_accel(self, a_vector_raw, a_vect_grav):
|
||||
x = a_vector_raw.x - a_vect_grav.x*8192
|
||||
y = a_vector_raw.y - a_vect_grav.y*8192
|
||||
z = a_vector_raw.z - a_vect_grav.z*8192
|
||||
return V(x, y, z)
|
||||
|
||||
|
||||
class MPU6050IRQHandler:
|
||||
__mpu = MPU6050
|
||||
__FIFO_buffer = list()
|
||||
__count = 0
|
||||
__packet_size = None
|
||||
__detected_error = False
|
||||
__logging = False
|
||||
__log_file = None
|
||||
__csv_writer = None
|
||||
__start_time = None
|
||||
__debug = None
|
||||
|
||||
# def __init__(self, a_i2c_bus, a_device_address, a_x_accel_offset,
|
||||
# a_y_accel_offset, a_z_accel_offset, a_x_gyro_offset,
|
||||
# a_y_gyro_offset, a_z_gyro_offset, a_enable_debug_output):
|
||||
# self.__mpu = MPU6050(a_i2c_bus, a_device_address, a_x_accel_offset,
|
||||
# a_y_accel_offset, a_z_accel_offset,
|
||||
# a_x_gyro_offset, a_y_gyro_offset, a_z_gyro_offset,
|
||||
# a_enable_debug_output)
|
||||
def __init__(self, a_mpu, a_logging=False, a_log_file='log.csv',
|
||||
a_debug=False):
|
||||
self.__mpu = a_mpu
|
||||
self.__FIFO_buffer = [0]*64
|
||||
self.__mpu.dmp_initialize()
|
||||
self.__mpu.set_DMP_enabled(True)
|
||||
self.__packet_size = self.__mpu.DMP_get_FIFO_packet_size()
|
||||
mpu_int_status = self.__mpu.get_int_status()
|
||||
if a_logging:
|
||||
self.__start_time = time.clock()
|
||||
self.__logging = True
|
||||
self.__log_file = open(a_log_file, 'ab')
|
||||
self.__csv_writer = csv.writer(self.__log_file, delimiter=',',
|
||||
quotechar='|',
|
||||
quoting=csv.QUOTE_MINIMAL)
|
||||
self.__debug = a_debug
|
||||
|
||||
def action(self, channel):
|
||||
if self.__detected_error:
|
||||
# Clear FIFO and reset MPU
|
||||
mpu_int_status = self.__mpu.get_int_status()
|
||||
self.__mpu.reset_FIFO()
|
||||
self.__detected_error = False
|
||||
return
|
||||
|
||||
try:
|
||||
FIFO_count = self.__mpu.get_FIFO_count()
|
||||
mpu_int_status = self.__mpu.get_int_status()
|
||||
except:
|
||||
self.__detected_error = True
|
||||
return
|
||||
|
||||
# If overflow is detected by status or fifo count we want to reset
|
||||
if (FIFO_count == 1024) or (mpu_int_status & 0x10):
|
||||
try:
|
||||
self.__mpu.reset_FIFO()
|
||||
except:
|
||||
self.__detected_error = True
|
||||
return
|
||||
|
||||
elif (mpu_int_status & 0x02):
|
||||
# Wait until packet_size number of bytes are ready for reading,
|
||||
# default is 42 bytes
|
||||
while FIFO_count < self.__packet_size:
|
||||
try:
|
||||
FIFO_count = self.__mpu.get_FIFO_count()
|
||||
except:
|
||||
self.__detected_error = True
|
||||
return
|
||||
|
||||
while FIFO_count > self.__packet_size:
|
||||
|
||||
try:
|
||||
self.__FIFO_buffer = \
|
||||
self.__mpu.get_FIFO_bytes(self.__packet_size)
|
||||
except:
|
||||
self.__detected_error = True
|
||||
return
|
||||
accel = \
|
||||
self.__mpu.DMP_get_acceleration_int16(self.__FIFO_buffer)
|
||||
quat = self.__mpu.DMP_get_quaternion_int16(self.__FIFO_buffer)
|
||||
grav = self.__mpu.DMP_get_gravity(quat)
|
||||
roll_pitch_yaw = self.__mpu.DMP_get_euler_roll_pitch_yaw(quat,
|
||||
grav)
|
||||
if self.__logging:
|
||||
delta_time = time.clock() - self.__start_time
|
||||
data_concat = ['%.4f' % delta_time] + \
|
||||
[accel.x, accel.y, accel.z] + \
|
||||
['%.3f' % roll_pitch_yaw.x,
|
||||
'%.3f' % roll_pitch_yaw.y,
|
||||
'%.3f' % roll_pitch_yaw.z]
|
||||
self.__csv_writer.writerow(data_concat)
|
||||
|
||||
if (self.__debug) and (self.__count % 100 == 0):
|
||||
print('roll: ' + str(roll_pitch_yaw.x))
|
||||
print('pitch: ' + str(roll_pitch_yaw.y))
|
||||
print('yaw: ' + str(roll_pitch_yaw.z))
|
||||
self.__count += 1
|
||||
FIFO_count -= self.__packet_size
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
########################################################################
|
||||
# Filename : MPU6050RAW.py
|
||||
# Description : Read data of MPU6050.
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import MPU6050
|
||||
import time
|
||||
|
||||
mpu = MPU6050.MPU6050() # instantiate a MPU6050 class object
|
||||
accel = [0]*3 # define an arry to store accelerometer data
|
||||
gyro = [0]*3 # define an arry to store gyroscope data
|
||||
def setup():
|
||||
mpu.dmp_initialize() # initialize MPU6050
|
||||
|
||||
def loop():
|
||||
while(True):
|
||||
accel = mpu.get_acceleration() # get accelerometer data
|
||||
gyro = mpu.get_rotation() # get gyroscope data
|
||||
print("a/g:%d\t%d\t%d\t%d\t%d\t%d "%(accel[0],accel[1],accel[2],gyro[0],gyro[1],gyro[2]))
|
||||
print("a/g:%.2f g\t%.2f g\t%.2f g\t%.2f d/s\t%.2f d/s\t%.2f d/s"%(accel[0]/16384.0,accel[1]/16384.0,
|
||||
accel[2]/16384.0,gyro[0]/131.0,gyro[1]/131.0,gyro[2]/131.0))
|
||||
time.sleep(0.1)
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print("Program is starting ... ")
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
pass
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
from MPU6050 import MPU6050
|
||||
from SimplePID import SimplePID
|
||||
|
||||
|
||||
def avg_from_array(a_array):
|
||||
sum = 0.0
|
||||
for index in range(0, len(a_array)):
|
||||
sum += a_array[index]
|
||||
|
||||
return sum/len(a_array)
|
||||
|
||||
|
||||
i2c_bus = 1
|
||||
device_address = 0x68
|
||||
# The offsets are different for each device and should be changed
|
||||
# accordingly using a calibration procedure
|
||||
x_accel_offset = 0
|
||||
y_accel_offset = 0
|
||||
z_accel_offset =0
|
||||
x_gyro_offset = 0
|
||||
y_gyro_offset = 0
|
||||
z_gyro_offset = 0
|
||||
enable_debug_output = True
|
||||
|
||||
mpu = MPU6050(i2c_bus, device_address, x_accel_offset, y_accel_offset,
|
||||
z_accel_offset, x_gyro_offset, y_gyro_offset, z_gyro_offset,
|
||||
enable_debug_output)
|
||||
|
||||
kp = 0.03125
|
||||
ki = 0.25
|
||||
kd = 0
|
||||
|
||||
pidax = SimplePID(0, -15000, 15000, kp, ki, kd, 100, True)
|
||||
piday = SimplePID(0, -15000, 15000, kp, ki, kd, 100, True)
|
||||
pidaz = SimplePID(0, -15000, 15000, kp, ki, kd, 100, True)
|
||||
pidgx = SimplePID(0, -15000, 15000, kp, ki, kd, 100, True)
|
||||
pidgy = SimplePID(0, -15000, 15000, kp, ki, kd, 100, True)
|
||||
pidgz = SimplePID(0, -15000, 15000, kp, ki, kd, 100, True)
|
||||
|
||||
accel_reading = mpu.get_acceleration()
|
||||
|
||||
x_accel_reading = accel_reading[0]
|
||||
y_accel_reading = accel_reading[1]
|
||||
z_accel_reading = accel_reading[2]
|
||||
|
||||
x_accel_avg = [0]*100
|
||||
y_accel_avg = [0]*100
|
||||
z_accel_avg = [0]*100
|
||||
|
||||
x_accel_offset_avg = [0]*100
|
||||
y_accel_offset_avg = [0]*100
|
||||
z_accel_offset_avg = [0]*100
|
||||
|
||||
axindex = 0
|
||||
ayindex = 0
|
||||
azindex = 0
|
||||
|
||||
gyro_reading = mpu.get_rotation()
|
||||
|
||||
x_gyro_reading = gyro_reading[0]
|
||||
y_gyro_reading = gyro_reading[1]
|
||||
z_gyro_reading = gyro_reading[2]
|
||||
|
||||
x_gyro_avg = [0]*100
|
||||
y_gyro_avg = [0]*100
|
||||
z_gyro_avg = [0]*100
|
||||
|
||||
x_gyro_offset_avg = [0]*100
|
||||
y_gyro_offset_avg = [0]*100
|
||||
z_gyro_offset_avg = [0]*100
|
||||
|
||||
gxindex = 0
|
||||
gyindex = 0
|
||||
gzindex = 0
|
||||
|
||||
try:
|
||||
while True:
|
||||
accel_reading = mpu.get_acceleration()
|
||||
x_accel_reading = accel_reading[0]
|
||||
y_accel_reading = accel_reading[1]
|
||||
z_accel_reading = accel_reading[2]
|
||||
|
||||
gyro_reading = mpu.get_rotation()
|
||||
x_gyro_reading = gyro_reading[0]
|
||||
y_gyro_reading = gyro_reading[1]
|
||||
z_gyro_reading = gyro_reading[2]
|
||||
|
||||
if pidax.check_time():
|
||||
x_accel_offset = pidax.get_output_value(x_accel_reading)
|
||||
|
||||
mpu.set_x_accel_offset(int(x_accel_offset))
|
||||
|
||||
x_accel_avg[axindex] = x_accel_reading
|
||||
x_accel_offset_avg[axindex] = x_accel_offset
|
||||
|
||||
axindex += 1
|
||||
if axindex == len(x_accel_avg):
|
||||
axindex = 0
|
||||
print('x_avg_read: ' +
|
||||
str(avg_from_array(x_accel_avg)) +
|
||||
' x_avg_offset: ' +
|
||||
str(avg_from_array(x_accel_offset_avg)))
|
||||
print('y_avg_read: ' +
|
||||
str(avg_from_array(y_accel_avg)) +
|
||||
' y_avg_offset: ' +
|
||||
str(avg_from_array(y_accel_offset_avg)))
|
||||
print('z_avg_read: ' +
|
||||
str(avg_from_array(z_accel_avg)) +
|
||||
' z_avg_offset: ' +
|
||||
str(avg_from_array(z_accel_offset_avg)))
|
||||
|
||||
if piday.check_time():
|
||||
y_accel_offset = piday.get_output_value(y_accel_reading)
|
||||
|
||||
mpu.set_y_accel_offset(int(y_accel_offset))
|
||||
|
||||
y_accel_avg[ayindex] = y_accel_reading
|
||||
y_accel_offset_avg[ayindex] = y_accel_offset
|
||||
|
||||
ayindex += 1
|
||||
if ayindex == len(y_accel_avg):
|
||||
ayindex = 0
|
||||
|
||||
if pidaz.check_time():
|
||||
z_accel_offset = pidaz.get_output_value(z_accel_reading)
|
||||
|
||||
mpu.set_z_accel_offset(int(z_accel_offset))
|
||||
|
||||
z_accel_avg[azindex] = z_accel_reading
|
||||
z_accel_offset_avg[azindex] = z_accel_offset
|
||||
|
||||
azindex += 1
|
||||
if azindex == len(z_accel_avg):
|
||||
azindex = 0
|
||||
|
||||
# Gyro calibration
|
||||
if pidgx.check_time():
|
||||
x_gyro_offset = pidgx.get_output_value(x_gyro_reading)
|
||||
|
||||
mpu.set_x_gyro_offset(int(x_gyro_offset))
|
||||
|
||||
x_gyro_avg[gxindex] = x_gyro_reading
|
||||
x_gyro_offset_avg[gxindex] = x_gyro_offset
|
||||
|
||||
gxindex += 1
|
||||
if gxindex == len(x_gyro_avg):
|
||||
gxindex = 0
|
||||
print('x_avg_read: ' +
|
||||
str(avg_from_array(x_gyro_avg)) +
|
||||
' x_avg_offset: ' +
|
||||
str(avg_from_array(x_gyro_offset_avg)))
|
||||
print('y_avg_read: ' +
|
||||
str(avg_from_array(y_gyro_avg)) +
|
||||
' y_avg_offset: ' +
|
||||
str(avg_from_array(y_gyro_offset_avg)))
|
||||
print('z_avg_read: ' +
|
||||
str(avg_from_array(z_gyro_avg)) +
|
||||
' z_avg_offset: ' +
|
||||
str(avg_from_array(z_gyro_offset_avg)))
|
||||
|
||||
if pidgy.check_time():
|
||||
y_gyro_offset = pidgy.get_output_value(y_gyro_reading)
|
||||
|
||||
mpu.set_y_gyro_offset(int(y_gyro_offset))
|
||||
|
||||
y_gyro_avg[gyindex] = y_gyro_reading
|
||||
y_gyro_offset_avg[gyindex] = y_gyro_offset
|
||||
|
||||
gyindex += 1
|
||||
if gyindex == len(y_gyro_avg):
|
||||
gyindex = 0
|
||||
|
||||
if pidgz.check_time():
|
||||
z_gyro_offset = pidgz.get_output_value(z_gyro_reading)
|
||||
|
||||
mpu.set_z_gyro_offset(int(z_gyro_offset))
|
||||
|
||||
z_gyro_avg[gzindex] = z_gyro_reading
|
||||
z_gyro_offset_avg[gzindex] = z_gyro_offset
|
||||
|
||||
gzindex += 1
|
||||
if gzindex == len(z_gyro_avg):
|
||||
gzindex = 0
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
+755
@@ -0,0 +1,755 @@
|
||||
__author__ = 'Geir Istad'
|
||||
|
||||
'''
|
||||
MPU6050 Python I2C Class
|
||||
Copyright (c) 2015 Geir Istad
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Code based on I2Cdev library collection - MPU6050 I2C device class
|
||||
by Jeff Rowberg <[email protected]>
|
||||
============================================
|
||||
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.
|
||||
===============================================
|
||||
'''
|
||||
|
||||
|
||||
class MPUConstants:
|
||||
# From MPU6050.h
|
||||
MPU6050_ADDRESS_AD0_LOW = 0x68 # address pin low (GND), default
|
||||
MPU6050_ADDRESS_AD0_HIGH = 0x69 # address pin high (VCC)
|
||||
MPU6050_DEFAULT_ADDRESS = MPU6050_ADDRESS_AD0_LOW
|
||||
|
||||
# [7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
MPU6050_RA_XG_OFFS_TC = 0x00
|
||||
# [7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
MPU6050_RA_YG_OFFS_TC = 0x01
|
||||
# [7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
MPU6050_RA_ZG_OFFS_TC = 0x02
|
||||
# [7:0] X_FINE_GAIN
|
||||
MPU6050_RA_X_FINE_GAIN = 0x03
|
||||
# [7:0] Y_FINE_GAIN
|
||||
MPU6050_RA_Y_FINE_GAIN = 0x04
|
||||
# [7:0] Z_FINE_GAIN
|
||||
MPU6050_RA_Z_FINE_GAIN = 0x05
|
||||
# [15:0] XA_OFFS
|
||||
MPU6050_RA_XA_OFFS_H = 0x06
|
||||
MPU6050_RA_XA_OFFS_L_TC = 0x07
|
||||
# [15:0] YA_OFFS
|
||||
MPU6050_RA_YA_OFFS_H = 0x08
|
||||
MPU6050_RA_YA_OFFS_L_TC = 0x09
|
||||
# [15:0] ZA_OFFS
|
||||
MPU6050_RA_ZA_OFFS_H = 0x0A
|
||||
MPU6050_RA_ZA_OFFS_L_TC = 0x0B
|
||||
# [15:0] XG_OFFS_USR
|
||||
MPU6050_RA_XG_OFFS_USRH = 0x13
|
||||
MPU6050_RA_XG_OFFS_USRL = 0x14
|
||||
# [15:0] YG_OFFS_USR
|
||||
MPU6050_RA_YG_OFFS_USRH = 0x15
|
||||
MPU6050_RA_YG_OFFS_USRL = 0x16
|
||||
# [15:0] ZG_OFFS_USR
|
||||
MPU6050_RA_ZG_OFFS_USRH = 0x17
|
||||
MPU6050_RA_ZG_OFFS_USRL = 0x18
|
||||
MPU6050_RA_SMPLRT_DIV = 0x19
|
||||
MPU6050_RA_CONFIG = 0x1A
|
||||
MPU6050_RA_GYRO_CONFIG = 0x1B
|
||||
MPU6050_RA_ACCEL_CONFIG = 0x1C
|
||||
MPU6050_RA_FF_THR = 0x1D
|
||||
MPU6050_RA_FF_DUR = 0x1E
|
||||
MPU6050_RA_MOT_THR = 0x1F
|
||||
MPU6050_RA_MOT_DUR = 0x20
|
||||
MPU6050_RA_ZRMOT_THR = 0x21
|
||||
MPU6050_RA_ZRMOT_DUR = 0x22
|
||||
MPU6050_RA_FIFO_EN = 0x23
|
||||
MPU6050_RA_I2C_MST_CTRL = 0x24
|
||||
MPU6050_RA_I2C_SLV0_ADDR = 0x25
|
||||
MPU6050_RA_I2C_SLV0_REG = 0x26
|
||||
MPU6050_RA_I2C_SLV0_CTRL = 0x27
|
||||
MPU6050_RA_I2C_SLV1_ADDR = 0x28
|
||||
MPU6050_RA_I2C_SLV1_REG = 0x29
|
||||
MPU6050_RA_I2C_SLV1_CTRL = 0x2A
|
||||
MPU6050_RA_I2C_SLV2_ADDR = 0x2B
|
||||
MPU6050_RA_I2C_SLV2_REG = 0x2C
|
||||
MPU6050_RA_I2C_SLV2_CTRL = 0x2D
|
||||
MPU6050_RA_I2C_SLV3_ADDR = 0x2E
|
||||
MPU6050_RA_I2C_SLV3_REG = 0x2F
|
||||
MPU6050_RA_I2C_SLV3_CTRL = 0x30
|
||||
MPU6050_RA_I2C_SLV4_ADDR = 0x31
|
||||
MPU6050_RA_I2C_SLV4_REG = 0x32
|
||||
MPU6050_RA_I2C_SLV4_DO = 0x33
|
||||
MPU6050_RA_I2C_SLV4_CTRL = 0x34
|
||||
MPU6050_RA_I2C_SLV4_DI = 0x35
|
||||
MPU6050_RA_I2C_MST_STATUS = 0x36
|
||||
MPU6050_RA_INT_PIN_CFG = 0x37
|
||||
MPU6050_RA_INT_ENABLE = 0x38
|
||||
MPU6050_RA_DMP_INT_STATUS = 0x39
|
||||
MPU6050_RA_INT_STATUS = 0x3A
|
||||
MPU6050_RA_ACCEL_XOUT_H = 0x3B
|
||||
MPU6050_RA_ACCEL_XOUT_L = 0x3C
|
||||
MPU6050_RA_ACCEL_YOUT_H = 0x3D
|
||||
MPU6050_RA_ACCEL_YOUT_L = 0x3E
|
||||
MPU6050_RA_ACCEL_ZOUT_H = 0x3F
|
||||
MPU6050_RA_ACCEL_ZOUT_L = 0x40
|
||||
MPU6050_RA_TEMP_OUT_H = 0x41
|
||||
MPU6050_RA_TEMP_OUT_L = 0x42
|
||||
MPU6050_RA_GYRO_XOUT_H = 0x43
|
||||
MPU6050_RA_GYRO_XOUT_L = 0x44
|
||||
MPU6050_RA_GYRO_YOUT_H = 0x45
|
||||
MPU6050_RA_GYRO_YOUT_L = 0x46
|
||||
MPU6050_RA_GYRO_ZOUT_H = 0x47
|
||||
MPU6050_RA_GYRO_ZOUT_L = 0x48
|
||||
MPU6050_RA_EXT_SENS_DATA_00 = 0x49
|
||||
MPU6050_RA_EXT_SENS_DATA_01 = 0x4A
|
||||
MPU6050_RA_EXT_SENS_DATA_02 = 0x4B
|
||||
MPU6050_RA_EXT_SENS_DATA_03 = 0x4C
|
||||
MPU6050_RA_EXT_SENS_DATA_04 = 0x4D
|
||||
MPU6050_RA_EXT_SENS_DATA_05 = 0x4E
|
||||
MPU6050_RA_EXT_SENS_DATA_06 = 0x4F
|
||||
MPU6050_RA_EXT_SENS_DATA_07 = 0x50
|
||||
MPU6050_RA_EXT_SENS_DATA_08 = 0x51
|
||||
MPU6050_RA_EXT_SENS_DATA_09 = 0x52
|
||||
MPU6050_RA_EXT_SENS_DATA_10 = 0x53
|
||||
MPU6050_RA_EXT_SENS_DATA_11 = 0x54
|
||||
MPU6050_RA_EXT_SENS_DATA_12 = 0x55
|
||||
MPU6050_RA_EXT_SENS_DATA_13 = 0x56
|
||||
MPU6050_RA_EXT_SENS_DATA_14 = 0x57
|
||||
MPU6050_RA_EXT_SENS_DATA_15 = 0x58
|
||||
MPU6050_RA_EXT_SENS_DATA_16 = 0x59
|
||||
MPU6050_RA_EXT_SENS_DATA_17 = 0x5A
|
||||
MPU6050_RA_EXT_SENS_DATA_18 = 0x5B
|
||||
MPU6050_RA_EXT_SENS_DATA_19 = 0x5C
|
||||
MPU6050_RA_EXT_SENS_DATA_20 = 0x5D
|
||||
MPU6050_RA_EXT_SENS_DATA_21 = 0x5E
|
||||
MPU6050_RA_EXT_SENS_DATA_22 = 0x5F
|
||||
MPU6050_RA_EXT_SENS_DATA_23 = 0x60
|
||||
MPU6050_RA_MOT_DETECT_STATUS = 0x61
|
||||
MPU6050_RA_I2C_SLV0_DO = 0x63
|
||||
MPU6050_RA_I2C_SLV1_DO = 0x64
|
||||
MPU6050_RA_I2C_SLV2_DO = 0x65
|
||||
MPU6050_RA_I2C_SLV3_DO = 0x66
|
||||
MPU6050_RA_I2C_MST_DELAY_CTRL = 0x67
|
||||
MPU6050_RA_SIGNAL_PATH_RESET = 0x68
|
||||
MPU6050_RA_MOT_DETECT_CTRL = 0x69
|
||||
MPU6050_RA_USER_CTRL = 0x6A
|
||||
MPU6050_RA_PWR_MGMT_1 = 0x6B
|
||||
MPU6050_RA_PWR_MGMT_2 = 0x6C
|
||||
MPU6050_RA_BANK_SEL = 0x6D
|
||||
MPU6050_RA_MEM_START_ADDR = 0x6E
|
||||
MPU6050_RA_MEM_R_W = 0x6F
|
||||
MPU6050_RA_DMP_CFG_1 = 0x70
|
||||
MPU6050_RA_DMP_CFG_2 = 0x71
|
||||
MPU6050_RA_FIFO_COUNTH = 0x72
|
||||
MPU6050_RA_FIFO_COUNTL = 0x73
|
||||
MPU6050_RA_FIFO_R_W = 0x74
|
||||
MPU6050_RA_WHO_AM_I = 0x75
|
||||
|
||||
MPU6050_TC_PWR_MODE_BIT = 7
|
||||
MPU6050_TC_OFFSET_BIT = 6
|
||||
MPU6050_TC_OFFSET_LENGTH = 6
|
||||
MPU6050_TC_OTP_BNK_VLD_BIT = 0
|
||||
|
||||
MPU6050_VDDIO_LEVEL_VLOGIC = 0
|
||||
MPU6050_VDDIO_LEVEL_VDD = 1
|
||||
|
||||
MPU6050_CFG_EXT_SYNC_SET_BIT = 5
|
||||
MPU6050_CFG_EXT_SYNC_SET_LENGTH = 3
|
||||
MPU6050_CFG_DLPF_CFG_BIT = 2
|
||||
MPU6050_CFG_DLPF_CFG_LENGTH = 3
|
||||
|
||||
MPU6050_EXT_SYNC_DISABLED = 0x0
|
||||
MPU6050_EXT_SYNC_TEMP_OUT_L = 0x1
|
||||
MPU6050_EXT_SYNC_GYRO_XOUT_L = 0x2
|
||||
MPU6050_EXT_SYNC_GYRO_YOUT_L = 0x3
|
||||
MPU6050_EXT_SYNC_GYRO_ZOUT_L = 0x4
|
||||
MPU6050_EXT_SYNC_ACCEL_XOUT_L = 0x5
|
||||
MPU6050_EXT_SYNC_ACCEL_YOUT_L = 0x6
|
||||
MPU6050_EXT_SYNC_ACCEL_ZOUT_L = 0x7
|
||||
|
||||
MPU6050_DLPF_BW_256 = 0x00
|
||||
MPU6050_DLPF_BW_188 = 0x01
|
||||
MPU6050_DLPF_BW_98 = 0x02
|
||||
MPU6050_DLPF_BW_42 = 0x03
|
||||
MPU6050_DLPF_BW_20 = 0x04
|
||||
MPU6050_DLPF_BW_10 = 0x05
|
||||
MPU6050_DLPF_BW_5 = 0x06
|
||||
|
||||
MPU6050_GCONFIG_FS_SEL_BIT = 4
|
||||
MPU6050_GCONFIG_FS_SEL_LENGTH = 2
|
||||
|
||||
MPU6050_GYRO_FS_250 = 0x00
|
||||
MPU6050_GYRO_FS_500 = 0x01
|
||||
MPU6050_GYRO_FS_1000 = 0x02
|
||||
MPU6050_GYRO_FS_2000 = 0x03
|
||||
|
||||
MPU6050_ACONFIG_XA_ST_BIT = 7
|
||||
MPU6050_ACONFIG_YA_ST_BIT = 6
|
||||
MPU6050_ACONFIG_ZA_ST_BIT = 5
|
||||
MPU6050_ACONFIG_AFS_SEL_BIT = 4
|
||||
MPU6050_ACONFIG_AFS_SEL_LENGTH = 2
|
||||
MPU6050_ACONFIG_ACCEL_HPF_BIT = 2
|
||||
MPU6050_ACONFIG_ACCEL_HPF_LENGTH = 3
|
||||
|
||||
MPU6050_ACCEL_FS_2 = 0x00
|
||||
MPU6050_ACCEL_FS_4 = 0x01
|
||||
MPU6050_ACCEL_FS_8 = 0x02
|
||||
MPU6050_ACCEL_FS_16 = 0x03
|
||||
|
||||
MPU6050_DHPF_RESET = 0x00
|
||||
MPU6050_DHPF_5 = 0x01
|
||||
MPU6050_DHPF_2P5 = 0x02
|
||||
MPU6050_DHPF_1P25 = 0x03
|
||||
MPU6050_DHPF_0P63 = 0x04
|
||||
MPU6050_DHPF_HOLD = 0x07
|
||||
|
||||
MPU6050_TEMP_FIFO_EN_BIT = 7
|
||||
MPU6050_XG_FIFO_EN_BIT = 6
|
||||
MPU6050_YG_FIFO_EN_BIT = 5
|
||||
MPU6050_ZG_FIFO_EN_BIT = 4
|
||||
MPU6050_ACCEL_FIFO_EN_BIT = 3
|
||||
MPU6050_SLV2_FIFO_EN_BIT = 2
|
||||
MPU6050_SLV1_FIFO_EN_BIT = 1
|
||||
MPU6050_SLV0_FIFO_EN_BIT = 0
|
||||
|
||||
MPU6050_MULT_MST_EN_BIT = 7
|
||||
MPU6050_WAIT_FOR_ES_BIT = 6
|
||||
MPU6050_SLV_3_FIFO_EN_BIT = 5
|
||||
MPU6050_I2C_MST_P_NSR_BIT = 4
|
||||
MPU6050_I2C_MST_CLK_BIT = 3
|
||||
MPU6050_I2C_MST_CLK_LENGTH = 4
|
||||
|
||||
MPU6050_CLOCK_DIV_348 = 0x0
|
||||
MPU6050_CLOCK_DIV_333 = 0x1
|
||||
MPU6050_CLOCK_DIV_320 = 0x2
|
||||
MPU6050_CLOCK_DIV_308 = 0x3
|
||||
MPU6050_CLOCK_DIV_296 = 0x4
|
||||
MPU6050_CLOCK_DIV_286 = 0x5
|
||||
MPU6050_CLOCK_DIV_276 = 0x6
|
||||
MPU6050_CLOCK_DIV_267 = 0x7
|
||||
MPU6050_CLOCK_DIV_258 = 0x8
|
||||
MPU6050_CLOCK_DIV_500 = 0x9
|
||||
MPU6050_CLOCK_DIV_471 = 0xA
|
||||
MPU6050_CLOCK_DIV_444 = 0xB
|
||||
MPU6050_CLOCK_DIV_421 = 0xC
|
||||
MPU6050_CLOCK_DIV_400 = 0xD
|
||||
MPU6050_CLOCK_DIV_381 = 0xE
|
||||
MPU6050_CLOCK_DIV_364 = 0xF
|
||||
|
||||
MPU6050_I2C_SLV_RW_BIT = 7
|
||||
MPU6050_I2C_SLV_ADDR_BIT = 6
|
||||
MPU6050_I2C_SLV_ADDR_LENGTH = 7
|
||||
MPU6050_I2C_SLV_EN_BIT = 7
|
||||
MPU6050_I2C_SLV_BYTE_SW_BIT = 6
|
||||
MPU6050_I2C_SLV_REG_DIS_BIT = 5
|
||||
MPU6050_I2C_SLV_GRP_BIT = 4
|
||||
MPU6050_I2C_SLV_LEN_BIT = 3
|
||||
MPU6050_I2C_SLV_LEN_LENGTH = 4
|
||||
|
||||
MPU6050_I2C_SLV4_RW_BIT = 7
|
||||
MPU6050_I2C_SLV4_ADDR_BIT = 6
|
||||
MPU6050_I2C_SLV4_ADDR_LENGTH = 7
|
||||
MPU6050_I2C_SLV4_EN_BIT = 7
|
||||
MPU6050_I2C_SLV4_INT_EN_BIT = 6
|
||||
MPU6050_I2C_SLV4_REG_DIS_BIT = 5
|
||||
MPU6050_I2C_SLV4_MST_DLY_BIT = 4
|
||||
MPU6050_I2C_SLV4_MST_DLY_LENGTH = 5
|
||||
|
||||
MPU6050_MST_PASS_THROUGH_BIT = 7
|
||||
MPU6050_MST_I2C_SLV4_DONE_BIT = 6
|
||||
MPU6050_MST_I2C_LOST_ARB_BIT = 5
|
||||
MPU6050_MST_I2C_SLV4_NACK_BIT = 4
|
||||
MPU6050_MST_I2C_SLV3_NACK_BIT = 3
|
||||
MPU6050_MST_I2C_SLV2_NACK_BIT = 2
|
||||
MPU6050_MST_I2C_SLV1_NACK_BIT = 1
|
||||
MPU6050_MST_I2C_SLV0_NACK_BIT = 0
|
||||
|
||||
MPU6050_INTCFG_INT_LEVEL_BIT = 7
|
||||
MPU6050_INTCFG_INT_OPEN_BIT = 6
|
||||
MPU6050_INTCFG_LATCH_INT_EN_BIT = 5
|
||||
MPU6050_INTCFG_INT_RD_CLEAR_BIT = 4
|
||||
MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT = 3
|
||||
MPU6050_INTCFG_FSYNC_INT_EN_BIT = 2
|
||||
MPU6050_INTCFG_I2C_BYPASS_EN_BIT = 1
|
||||
MPU6050_INTCFG_CLKOUT_EN_BIT = 0
|
||||
|
||||
MPU6050_INTMODE_ACTIVEHIGH = 0x00
|
||||
MPU6050_INTMODE_ACTIVELOW = 0x01
|
||||
|
||||
MPU6050_INTDRV_PUSHPULL = 0x00
|
||||
MPU6050_INTDRV_OPENDRAIN = 0x01
|
||||
|
||||
MPU6050_INTLATCH_50USPULSE = 0x00
|
||||
MPU6050_INTLATCH_WAITCLEAR = 0x01
|
||||
|
||||
MPU6050_INTCLEAR_STATUSREAD = 0x00
|
||||
MPU6050_INTCLEAR_ANYREAD = 0x01
|
||||
|
||||
MPU6050_INTERRUPT_FF_BIT = 7
|
||||
MPU6050_INTERRUPT_MOT_BIT = 6
|
||||
MPU6050_INTERRUPT_ZMOT_BIT = 5
|
||||
MPU6050_INTERRUPT_FIFO_OFLOW_BIT = 4
|
||||
MPU6050_INTERRUPT_I2C_MST_INT_BIT = 3
|
||||
MPU6050_INTERRUPT_PLL_RDY_INT_BIT = 2
|
||||
MPU6050_INTERRUPT_DMP_INT_BIT = 1
|
||||
MPU6050_INTERRUPT_DATA_RDY_BIT = 0
|
||||
|
||||
# TODO: figure out what these actually do
|
||||
# UMPL source code is not very obivous
|
||||
MPU6050_DMPINT_5_BIT = 5
|
||||
MPU6050_DMPINT_4_BIT = 4
|
||||
MPU6050_DMPINT_3_BIT = 3
|
||||
MPU6050_DMPINT_2_BIT = 2
|
||||
MPU6050_DMPINT_1_BIT = 1
|
||||
MPU6050_DMPINT_0_BIT = 0
|
||||
|
||||
MPU6050_MOTION_MOT_XNEG_BIT = 7
|
||||
MPU6050_MOTION_MOT_XPOS_BIT = 6
|
||||
MPU6050_MOTION_MOT_YNEG_BIT = 5
|
||||
MPU6050_MOTION_MOT_YPOS_BIT = 4
|
||||
MPU6050_MOTION_MOT_ZNEG_BIT = 3
|
||||
MPU6050_MOTION_MOT_ZPOS_BIT = 2
|
||||
MPU6050_MOTION_MOT_ZRMOT_BIT = 0
|
||||
|
||||
MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT = 7
|
||||
MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT = 4
|
||||
MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT = 3
|
||||
MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT = 2
|
||||
MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT = 1
|
||||
MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT = 0
|
||||
|
||||
MPU6050_PATHRESET_GYRO_RESET_BIT = 2
|
||||
MPU6050_PATHRESET_ACCEL_RESET_BIT = 1
|
||||
MPU6050_PATHRESET_TEMP_RESET_BIT = 0
|
||||
|
||||
MPU6050_DETECT_ACCEL_ON_DELAY_BIT = 5
|
||||
MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH = 2
|
||||
MPU6050_DETECT_FF_COUNT_BIT = 3
|
||||
MPU6050_DETECT_FF_COUNT_LENGTH = 2
|
||||
MPU6050_DETECT_MOT_COUNT_BIT = 1
|
||||
MPU6050_DETECT_MOT_COUNT_LENGTH = 2
|
||||
|
||||
MPU6050_DETECT_DECREMENT_RESET = 0x0
|
||||
MPU6050_DETECT_DECREMENT_1 = 0x1
|
||||
MPU6050_DETECT_DECREMENT_2 = 0x2
|
||||
MPU6050_DETECT_DECREMENT_4 = 0x3
|
||||
|
||||
MPU6050_USERCTRL_DMP_EN_BIT = 7
|
||||
MPU6050_USERCTRL_FIFO_EN_BIT = 6
|
||||
MPU6050_USERCTRL_I2C_MST_EN_BIT = 5
|
||||
MPU6050_USERCTRL_I2C_IF_DIS_BIT = 4
|
||||
MPU6050_USERCTRL_DMP_RESET_BIT = 3
|
||||
MPU6050_USERCTRL_FIFO_RESET_BIT = 2
|
||||
MPU6050_USERCTRL_I2C_MST_RESET_BIT = 1
|
||||
MPU6050_USERCTRL_SIG_COND_RESET_BIT = 0
|
||||
|
||||
MPU6050_PWR1_DEVICE_RESET_BIT = 7
|
||||
MPU6050_PWR1_SLEEP_BIT = 6
|
||||
MPU6050_PWR1_CYCLE_BIT = 5
|
||||
MPU6050_PWR1_TEMP_DIS_BIT = 3
|
||||
MPU6050_PWR1_CLKSEL_BIT = 2
|
||||
MPU6050_PWR1_CLKSEL_LENGTH = 3
|
||||
|
||||
MPU6050_CLOCK_INTERNAL = 0x00
|
||||
MPU6050_CLOCK_PLL_XGYRO = 0x01
|
||||
MPU6050_CLOCK_PLL_YGYRO = 0x02
|
||||
MPU6050_CLOCK_PLL_ZGYRO = 0x03
|
||||
MPU6050_CLOCK_PLL_EXT32K = 0x04
|
||||
MPU6050_CLOCK_PLL_EXT19M = 0x05
|
||||
MPU6050_CLOCK_KEEP_RESET = 0x07
|
||||
|
||||
MPU6050_PWR2_LP_WAKE_CTRL_BIT = 7
|
||||
MPU6050_PWR2_LP_WAKE_CTRL_LENGTH = 2
|
||||
MPU6050_PWR2_STBY_XA_BIT = 5
|
||||
MPU6050_PWR2_STBY_YA_BIT = 4
|
||||
MPU6050_PWR2_STBY_ZA_BIT = 3
|
||||
MPU6050_PWR2_STBY_XG_BIT = 2
|
||||
MPU6050_PWR2_STBY_YG_BIT = 1
|
||||
MPU6050_PWR2_STBY_ZG_BIT = 0
|
||||
|
||||
MPU6050_WAKE_FREQ_1P25 = 0x0
|
||||
MPU6050_WAKE_FREQ_2P5 = 0x1
|
||||
MPU6050_WAKE_FREQ_5 = 0x2
|
||||
MPU6050_WAKE_FREQ_10 = 0x3
|
||||
|
||||
MPU6050_BANKSEL_PRFTCH_EN_BIT = 6
|
||||
MPU6050_BANKSEL_CFG_USER_BANK_BIT = 5
|
||||
MPU6050_BANKSEL_MEM_SEL_BIT = 4
|
||||
MPU6050_BANKSEL_MEM_SEL_LENGTH = 5
|
||||
|
||||
MPU6050_WHO_AM_I_BIT = 6
|
||||
MPU6050_WHO_AM_I_LENGTH = 6
|
||||
|
||||
MPU6050_DMP_MEMORY_BANKS = 8
|
||||
MPU6050_DMP_MEMORY_BANK_SIZE = 256
|
||||
MPU6050_DMP_MEMORY_CHUNK_SIZE = 16
|
||||
|
||||
# From MPU6050_6Axis_MotionApps20.h
|
||||
MPU6050_DMP_CODE_SIZE = 1929 # dmpMemory[]
|
||||
MPU6050_DMP_CONFIG_SIZE = 192 # dmpConfig[]
|
||||
MPU6050_DMP_UPDATES_SIZE = 47 # dmpUpdates[]
|
||||
'''
|
||||
* ================================================================================================ *
|
||||
| Default MotionApps v2.0 42-byte FIFO packet structure: |
|
||||
| |
|
||||
| [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] |
|
||||
| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
||||
| |
|
||||
| [GYRO Z][ ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] |
|
||||
| 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
||||
* ================================================================================================ *
|
||||
'''
|
||||
# dmpMemory has size MPU6050_DMP_CODE_SIZE = 1929
|
||||
dmpMemory = [
|
||||
# bank 0, 256 bytes
|
||||
0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02,
|
||||
0x00, 0x03, 0x00, 0x00,
|
||||
0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B,
|
||||
0x12, 0x82, 0x00, 0x01,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF,
|
||||
0xFF, 0xFE, 0x80, 0x01,
|
||||
0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09,
|
||||
0x3E, 0x80, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00,
|
||||
0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55,
|
||||
0x00, 0x00, 0x21, 0x82,
|
||||
0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00,
|
||||
0x00, 0x05, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32,
|
||||
0x00, 0x00, 0x5E, 0xC0,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B,
|
||||
0x00, 0x6C, 0x12, 0xCC,
|
||||
0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00,
|
||||
0x40, 0x00, 0x01, 0xF4,
|
||||
0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6,
|
||||
0x00, 0x00, 0x27, 0x10,
|
||||
|
||||
# bank 1, 256 bytes
|
||||
0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0,
|
||||
0xFF, 0xD9, 0x5B, 0xC8,
|
||||
0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2,
|
||||
0x00, 0xCE, 0xBB, 0xF7,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02,
|
||||
0x02, 0x00, 0x00, 0x0C,
|
||||
0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x00, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC,
|
||||
0xC6, 0x7E, 0xD1, 0x6C,
|
||||
0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE,
|
||||
0x00, 0x0C, 0x02, 0xD0,
|
||||
|
||||
# bank 2, 256 bytes
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00,
|
||||
0xFF, 0xEF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
# bank 3, 256 bytes
|
||||
0xD8, 0xDC, 0xBA, 0xA2, 0xF1, 0xDE, 0xB2, 0xB8, 0xB4, 0xA8, 0x81, 0x91,
|
||||
0xF7, 0x4A, 0x90, 0x7F,
|
||||
0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, 0xA0, 0x80, 0xF2,
|
||||
0xCE, 0x81, 0xF3, 0xC2,
|
||||
0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, 0xF1, 0xC6, 0xD8,
|
||||
0x80, 0xBA, 0xA7, 0xDF,
|
||||
0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, 0x87, 0xA2, 0x94,
|
||||
0x24, 0x48, 0x70, 0x3C,
|
||||
0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, 0x83, 0x92, 0x2D,
|
||||
0x55, 0x7D, 0xD8, 0xB1,
|
||||
0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, 0x70, 0xF2, 0x7C,
|
||||
0x80, 0xA8, 0xF1, 0x01,
|
||||
0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, 0xBA, 0xA1, 0xF2,
|
||||
0x0E, 0xB8, 0x97, 0x80,
|
||||
0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0xC5,
|
||||
0xCD, 0xC7, 0xA9, 0x0C,
|
||||
0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, 0x26, 0x46, 0x66,
|
||||
0xB0, 0xB4, 0xBA, 0x80,
|
||||
0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, 0xB6, 0x98, 0x00,
|
||||
0x89, 0x0E, 0x16, 0x1E,
|
||||
0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, 0xA8, 0x96, 0x36,
|
||||
0x56, 0x76, 0xF1, 0xB9,
|
||||
0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB1, 0x8F, 0x98,
|
||||
0xB9, 0xAF, 0xF0, 0x24,
|
||||
0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, 0x7D, 0xAF, 0x83,
|
||||
0xB5, 0x93, 0xAF, 0xF0,
|
||||
0x00, 0x28, 0x50, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF,
|
||||
0xD9, 0xFA, 0xA3, 0x86,
|
||||
0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5,
|
||||
0xC7, 0xB2, 0x8C, 0xC1,
|
||||
0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1,
|
||||
0xB8, 0xA8, 0xB2, 0x86,
|
||||
|
||||
# bank 4, 256 bytes
|
||||
0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35,
|
||||
0x3D, 0xB2, 0xB6, 0xBA,
|
||||
0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A,
|
||||
0xB8, 0xAA, 0x87, 0x2C,
|
||||
0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4,
|
||||
0xCD, 0xC9, 0xF1, 0xB8,
|
||||
0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55,
|
||||
0x7D, 0xB5, 0x93, 0xA3,
|
||||
0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97,
|
||||
0x83, 0xA8, 0x11, 0x84,
|
||||
0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64,
|
||||
0x18, 0xD8, 0xF1, 0xA5,
|
||||
0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A,
|
||||
0x40, 0x48, 0xF9, 0xF3,
|
||||
0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18,
|
||||
0x97, 0x82, 0xA8, 0xF1,
|
||||
0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3,
|
||||
0xDE, 0xD8, 0x83, 0xA5,
|
||||
0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1,
|
||||
0x84, 0x92, 0xA2, 0x4D,
|
||||
0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32,
|
||||
0xD8, 0x50, 0x71, 0xD9,
|
||||
0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8,
|
||||
0x78, 0x93, 0xA3, 0x4D,
|
||||
0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32,
|
||||
0xD8, 0x50, 0x71, 0xD9,
|
||||
0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8,
|
||||
0x78, 0xA8, 0x8A, 0x9A,
|
||||
0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98,
|
||||
0xA8, 0xD9, 0x08, 0xD8,
|
||||
0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1,
|
||||
0xAF, 0xC8, 0x97, 0x87,
|
||||
|
||||
# bank 5, 256 bytes
|
||||
0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D,
|
||||
0xF3, 0xD9, 0x2A, 0xD8,
|
||||
0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9,
|
||||
0x61, 0xD8, 0x6C, 0x68,
|
||||
0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3,
|
||||
0x84, 0x19, 0x3D, 0x5D,
|
||||
0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8,
|
||||
0xB0, 0xAF, 0x8F, 0x94,
|
||||
0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8,
|
||||
0x87, 0x9A, 0x35, 0xDA,
|
||||
0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98,
|
||||
0x85, 0x02, 0x2E, 0x56,
|
||||
0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9,
|
||||
0x28, 0xD8, 0x4D, 0xD9,
|
||||
0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8,
|
||||
0xA3, 0x29, 0x83, 0xDA,
|
||||
0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8,
|
||||
0xB8, 0xB0, 0xA8, 0x8A,
|
||||
0x9A, 0xF5, 0x20, 0xAA, 0xDA, 0xDF, 0xD8, 0xA8, 0x40, 0xAA, 0xD0, 0xDA,
|
||||
0xDE, 0xD8, 0xA8, 0x60,
|
||||
0xAA, 0xDA, 0xD0, 0xDF, 0xD8, 0xF1, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06,
|
||||
0x99, 0x07, 0xAB, 0x97,
|
||||
0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, 0xB8, 0xB0, 0xB4, 0xA8,
|
||||
0x8C, 0x9C, 0xF0, 0x04,
|
||||
0x28, 0x51, 0x79, 0x1D, 0x30, 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98,
|
||||
0x2C, 0x50, 0x50, 0x78,
|
||||
0x78, 0x9B, 0xF1, 0x1A, 0xB0, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79,
|
||||
0x8B, 0x29, 0x51, 0x79,
|
||||
0x8A, 0x24, 0x70, 0x59, 0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38,
|
||||
0x8B, 0x39, 0x40, 0x68,
|
||||
0x8A, 0x64, 0x48, 0x31, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09,
|
||||
0x71, 0x58, 0x44, 0x68,
|
||||
|
||||
# bank 6, 256 bytes
|
||||
0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C,
|
||||
0xF0, 0x8C, 0xA8, 0x04,
|
||||
0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C,
|
||||
0x02, 0x26, 0x46, 0x66,
|
||||
0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69,
|
||||
0x38, 0x64, 0x48, 0x31,
|
||||
0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8,
|
||||
0x19, 0x31, 0x48, 0x60,
|
||||
0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19,
|
||||
0x86, 0xA8, 0x6E, 0x76,
|
||||
0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22,
|
||||
0x8A, 0x6E, 0x8A, 0x56,
|
||||
0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E,
|
||||
0x6E, 0x9D, 0xB8, 0xAD,
|
||||
0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D,
|
||||
0x55, 0x7D, 0x81, 0x91,
|
||||
0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8,
|
||||
0x4D, 0xD9, 0x48, 0xD8,
|
||||
0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8,
|
||||
0x51, 0xD9, 0x04, 0xAE,
|
||||
0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE,
|
||||
0x19, 0x81, 0xAD, 0xD9,
|
||||
0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7,
|
||||
0xD9, 0xAD, 0xAD, 0xAD,
|
||||
0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E,
|
||||
0x76, 0xF3, 0xAC, 0x2E,
|
||||
0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C,
|
||||
0xAC, 0x30, 0x18, 0xA8,
|
||||
0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C,
|
||||
0x24, 0xF2, 0xB0, 0x89,
|
||||
0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51,
|
||||
0xD9, 0xD8, 0xD8, 0x79,
|
||||
|
||||
# bank 7, 138 bytes (remainder)
|
||||
0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91,
|
||||
0x2D, 0xD9, 0x28, 0xD8,
|
||||
0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35,
|
||||
0x3D, 0x80, 0x25, 0xDA,
|
||||
0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28,
|
||||
0x34, 0x3C, 0xF3, 0xAB,
|
||||
0x8B, 0xF8, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xFA, 0xB0,
|
||||
0x87, 0x9C, 0xB9, 0xA3,
|
||||
0xDD, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x95, 0xF1, 0xA3, 0xA3, 0xA3, 0x9D,
|
||||
0xF1, 0xA3, 0xA3, 0xA3,
|
||||
0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
|
||||
0xA3, 0xA3, 0xA3, 0xA3,
|
||||
0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99,
|
||||
0xF1, 0xA3, 0xA3, 0xA3,
|
||||
0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3,
|
||||
0x9B, 0xA3, 0xA3, 0xDC,
|
||||
0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF]
|
||||
|
||||
# dmpConfig has size MPU6050_DMP_CONFIG_SIZE = 192
|
||||
dmpConfig = [
|
||||
# BANK OFFSET LENGTH [DATA]
|
||||
0x03, 0x7B, 0x03, 0x4C, 0xCD, 0x6C, # FCFG_1 inv_set_gyro_calibration
|
||||
0x03, 0xAB, 0x03, 0x36, 0x56, 0x76, # FCFG_3 inv_set_gyro_calibration
|
||||
0x00, 0x68, 0x04, 0x02, 0xCB, 0x47, 0xA2,
|
||||
# D_0_104 inv_set_gyro_calibration
|
||||
0x02, 0x18, 0x04, 0x00, 0x05, 0x8B, 0xC1,
|
||||
# D_0_24 inv_set_gyro_calibration
|
||||
0x01, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
# D_1_152 inv_set_accel_calibration
|
||||
0x03, 0x7F, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97,
|
||||
# FCFG_2 inv_set_accel_calibration
|
||||
0x03, 0x89, 0x03, 0x26, 0x46, 0x66, # FCFG_7 inv_set_accel_calibration
|
||||
0x00, 0x6C, 0x02, 0x20, 0x00, # D_0_108 inv_set_accel_calibration
|
||||
0x02, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
# CPASS_MTX_00 inv_set_compass_calibration
|
||||
0x02, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_01
|
||||
0x02, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_02
|
||||
0x02, 0x4C, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_10
|
||||
0x02, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_11
|
||||
0x02, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_12
|
||||
0x02, 0x58, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_20
|
||||
0x02, 0x5C, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_21
|
||||
0x02, 0xBC, 0x04, 0x00, 0x00, 0x00, 0x00, # CPASS_MTX_22
|
||||
0x01, 0xEC, 0x04, 0x00, 0x00, 0x40, 0x00,
|
||||
# D_1_236 inv_apply_endian_accel
|
||||
0x03, 0x7F, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97,
|
||||
# FCFG_2 inv_set_mpu_sensors
|
||||
0x04, 0x02, 0x03, 0x0D, 0x35, 0x5D,
|
||||
# CFG_MOTION_BIAS inv_turn_on_bias_from_no_motion
|
||||
0x04, 0x09, 0x04, 0x87, 0x2D, 0x35, 0x3D, # FCFG_5 inv_set_bias_update
|
||||
0x00, 0xA3, 0x01, 0x00, # D_0_163 inv_set_dead_zone
|
||||
# SPECIAL 0x01 = enable interrupts
|
||||
0x00, 0x00, 0x00, 0x01, # SET INT_ENABLE at i=22, SPECIAL INSTRUCTION
|
||||
0x07, 0x86, 0x01, 0xFE, # CFG_6 inv_set_fifo_interupt
|
||||
0x07, 0x41, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38,
|
||||
# CFG_8 inv_send_quaternion
|
||||
0x07, 0x7E, 0x01, 0x30, # CFG_16 inv_set_footer
|
||||
0x07, 0x46, 0x01, 0x9A, # CFG_GYRO_SOURCE inv_send_gyro
|
||||
0x07, 0x47, 0x04, 0xF1, 0x28, 0x30, 0x38,
|
||||
# CFG_9 inv_send_gyro -> inv_construct3_fifo
|
||||
0x07, 0x6C, 0x04, 0xF1, 0x28, 0x30, 0x38,
|
||||
# CFG_12 inv_send_accel -> inv_construct3_fifo
|
||||
0x02, 0x16, 0x02, 0x00, 0x01] # D_0_22 inv_set_fifo_rate
|
||||
|
||||
# This very last 0x01 WAS a 0x09, which drops the FIFO rate down to 20 Hz.
|
||||
# 0x07 is 25 Hz, 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends
|
||||
# to result in very noisy data. DMP output frequency is calculated easily
|
||||
# using this equation: (200Hz / (1 + value))
|
||||
|
||||
# It is important to make sure the host processor can keep up with reading
|
||||
# and processing the FIFO output at the desired rate. Handling FIFO overflow
|
||||
# cleanly is also a good idea.
|
||||
|
||||
# dmpUpdates has size MPU6050_DMP_UPDATES_SIZE = 47
|
||||
dmpUpdates = [
|
||||
0x01, 0xB2, 0x02, 0xFF, 0xFF,
|
||||
0x01, 0x90, 0x04, 0x09, 0x23, 0xA1, 0x35,
|
||||
0x01, 0x6A, 0x02, 0x06, 0x00,
|
||||
0x01, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00,
|
||||
0x01, 0x62, 0x02, 0x00, 0x00,
|
||||
0x00, 0x60, 0x04, 0x00, 0x40, 0x00, 0x00]
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
__author__ = 'Geir Istad'
|
||||
"""
|
||||
MPU6050 Python I2C Class
|
||||
Copyright (c) 2015 Geir Istad
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Code based on
|
||||
I2Cdev library collection - 3D math helper
|
||||
by Jeff Rowberg <[email protected]>
|
||||
============================================
|
||||
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.
|
||||
===============================================
|
||||
"""
|
||||
from math import sqrt
|
||||
|
||||
|
||||
class Quaternion:
|
||||
w = 0.0
|
||||
x = 0.0
|
||||
y = 0.0
|
||||
z = 0.0
|
||||
|
||||
def __init__(self, a_w=1.0, a_x=0.0, a_y=0.0, a_z=0.0):
|
||||
self.w = a_w
|
||||
self.x = a_x
|
||||
self.y = a_y
|
||||
self.z = a_z
|
||||
|
||||
def get_product(self, a_quat):
|
||||
result = Quaternion(
|
||||
self.w * a_quat.w - self.x * a_quat.x -
|
||||
self.y * a_quat.y - self.z * a_quat.z,
|
||||
|
||||
self.w * a_quat.x + self.x * a_quat.w +
|
||||
self.y * a_quat.z - self.z * a_quat.y,
|
||||
|
||||
self.w * a_quat.y - self.x * a_quat.z +
|
||||
self.y * a_quat.w + self.z * a_quat.x,
|
||||
|
||||
self.w * a_quat.z + self.x * a_quat.y -
|
||||
self.y * a_quat.x + self.z * a_quat.w)
|
||||
return result
|
||||
|
||||
def get_conjugate(self):
|
||||
result = Quaternion(self.w, -self.x, -self.y, -self.z)
|
||||
return result
|
||||
|
||||
def get_magnitude(self):
|
||||
return sqrt(self.w * self.w + self.x * self.x + self.y * self.y +
|
||||
self.z * self.z)
|
||||
|
||||
def normalize(self):
|
||||
m = self.get_magnitude()
|
||||
self.w = self.w / m
|
||||
self.x = self.x / m
|
||||
self.y = self.y / m
|
||||
self.z = self.z / m
|
||||
|
||||
def get_normalized(self):
|
||||
result = Quaternion(self.w, self.x, self.y, self.z)
|
||||
result.normalize()
|
||||
return result
|
||||
|
||||
|
||||
class XYZVector:
|
||||
x = 0.0
|
||||
y = 0.0
|
||||
z = 0.0
|
||||
|
||||
def __init__(self, a_x=0.0, a_y=0.0, a_z=0.0):
|
||||
self.x = a_x
|
||||
self.y = a_y
|
||||
self.z = a_z
|
||||
|
||||
def get_magnitude(self):
|
||||
return sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
|
||||
|
||||
def normalize(self):
|
||||
m = self.get_magnitude()
|
||||
self.x = self.x / m
|
||||
self.y = self.y / m
|
||||
self.z = self.z / m
|
||||
|
||||
def get_normalized(self):
|
||||
result = XYZVector(self.x, self.y, self.z)
|
||||
result.normalize()
|
||||
return result
|
||||
|
||||
def rotate(self, a_quat):
|
||||
p = Quaternion(0.0, self.x, self.y, self.z)
|
||||
p = a_quat.get_product(p)
|
||||
p = p.get_product(a_quat.get_conjugate())
|
||||
# By magic quaternion p is now [0, x', y', z']
|
||||
self.x = p.x
|
||||
self.y = p.y
|
||||
self.z = p.z
|
||||
|
||||
def get_rotated(self, a_quat):
|
||||
r = XYZVector(self.x, self.y, self.z)
|
||||
r.rotate(a_quat)
|
||||
return r
|
||||
@@ -0,0 +1,69 @@
|
||||
import RPi.GPIO as GPIO
|
||||
import os
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
host_name = '192.168.1.112' # Change this to your Raspberry Pi IP address
|
||||
host_port = 8000
|
||||
|
||||
class MyServer(BaseHTTPRequestHandler):
|
||||
""" A special implementation of BaseHTTPRequestHander for reading data from
|
||||
and control GPIO of a Raspberry Pi
|
||||
"""
|
||||
def do_HEAD(self):
|
||||
""" do_HEAD() can be tested use curl command
|
||||
'curl -I http://server-ip-address:port'
|
||||
"""
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/html')
|
||||
self.end_headers()
|
||||
def _redirect(self, path):
|
||||
self.send_response(303)
|
||||
self.send_header('Content-type', 'text/html')
|
||||
self.send_header('Location', path)
|
||||
self.end_headers()
|
||||
def do_GET(self):
|
||||
""" do_GET() can be tested using curl command
|
||||
'curl http://server-ip-address:port'
|
||||
"""
|
||||
html = '''
|
||||
<html>
|
||||
<body style="width:960px; margin: 20px auto;">
|
||||
<h1>Welcome to my Raspberry Pi</h1>
|
||||
<p>Current GPU temperature is {}</p>
|
||||
<form action="/" method="POST">
|
||||
Turn LED :
|
||||
<input type="submit" name="submit" value="On">
|
||||
<input type="submit" name="submit" value="Off">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
temp = os.popen("/opt/vc/bin/vcgencmd measure_temp").read()
|
||||
self.do_HEAD()
|
||||
self.wfile.write(html.format(temp[5:]).encode("utf-8"))
|
||||
def do_POST(self):
|
||||
""" do_POST() can be tested using curl command
|
||||
'curl -d "submit=On" http://server-ip-address:port'
|
||||
"""
|
||||
content_length = int(self.headers['Content-Length']) # Get the size of data
|
||||
post_data = self.rfile.read(content_length).decode("utf-8") # Get the data
|
||||
post_data = post_data.split("=")[1] # Only keep the value
|
||||
# GPIO setup
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setup(17,GPIO.OUT) # You can also choose to use other GPIO
|
||||
if post_data == 'On':
|
||||
GPIO.output(17, GPIO.HIGH)
|
||||
else:
|
||||
GPIO.output(17, GPIO.LOW)
|
||||
print("LED is {}".format(post_data))
|
||||
self._redirect('/') # Redirect back to the root url
|
||||
|
||||
if __name__ == '__main__':
|
||||
http_server = HTTPServer((host_name, host_port), MyServer)
|
||||
print("Server Starts - %s:%s" % (host_name, host_port))
|
||||
try:
|
||||
http_server.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
http_server.server_close()
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
# Filename : LightWater03.py
|
||||
# Description : Control LED with 74HC595 on the DIY circuit board
|
||||
# Author : www.freenove.com
|
||||
# modification: 2019/12/28
|
||||
########################################################################
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
LSBFIRST = 1
|
||||
MSBFIRST = 2
|
||||
|
||||
# define the pins connect to 74HC595
|
||||
dataPin = 11 # DS Pin of 74HC595(Pin14)
|
||||
latchPin = 13 # ST_CP Pin of 74HC595(Pin12)
|
||||
clockPin = 15 # SH_CP Pin of 74HC595(Pin11)
|
||||
|
||||
# Define an array to store the pulse width of LED
|
||||
pluseWidth = [0,0,0,0,0,0,0,0,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0]
|
||||
|
||||
def setup():
|
||||
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
|
||||
GPIO.setup(dataPin, GPIO.OUT) # set dataPin to OUTPUT mode
|
||||
GPIO.setup(latchPin, GPIO.OUT) # set latchPin to OUTPUT mode
|
||||
GPIO.setup(clockPin, GPIO.OUT) # set clockPin to OUTPUT mode
|
||||
|
||||
def shiftOut(dPin,cPin,order,val):
|
||||
for i in range(0,8):
|
||||
GPIO.output(cPin,GPIO.LOW);
|
||||
if(order == LSBFIRST):
|
||||
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
|
||||
elif(order == MSBFIRST):
|
||||
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
|
||||
GPIO.output(cPin,GPIO.HIGH);
|
||||
|
||||
def outData(data):
|
||||
GPIO.output(latchPin,GPIO.LOW)
|
||||
shiftOut(dataPin,clockPin,LSBFIRST,data)
|
||||
GPIO.output(latchPin,GPIO.HIGH)
|
||||
|
||||
def loop():
|
||||
moveSpeed = 0.1 # moveSpeed works like a relay, the larger, the slower
|
||||
index = 0 # array index starts from 0
|
||||
lastMove = time.time() # record the start time
|
||||
while True:
|
||||
if(time.time() - lastMove > moveSpeed): # control speed
|
||||
lastMove = time.time() # Record the time point of the move
|
||||
index +=1 # move to next
|
||||
if(index > 15): # index to 0
|
||||
index = 0
|
||||
|
||||
for i in range(0,64): # The cycle of PWM is 64 cycles
|
||||
data = 0
|
||||
for j in range(0,8): #Calculate the output state of this loop
|
||||
if(i < pluseWidth[j+index]): #Calculate the LED state according to the pulse width
|
||||
data |= 1<<j # Calculate the data
|
||||
outData(data) # Send the data to 74HC595
|
||||
|
||||
def destroy():
|
||||
GPIO.cleanup()
|
||||
|
||||
if __name__ == '__main__': # Program entrance
|
||||
print ('Program is starting...')
|
||||
setup()
|
||||
try:
|
||||
loop()
|
||||
except KeyboardInterrupt: # Press ctrl-c to end the program.
|
||||
destroy()
|
||||
Reference in New Issue
Block a user