adding projects
This commit is contained in:
commit
e22f5a84ce
56
projects/CountDown/TrumpCountdown.ino
Normal file
56
projects/CountDown/TrumpCountdown.ino
Normal file
@ -0,0 +1,56 @@
|
||||
/* SevSeg Counter Example
|
||||
|
||||
Copyright 2017 Dean Reading
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
This example demonstrates a very simple use of the SevSeg library with a 4
|
||||
digit display. It displays a counter that counts up, showing deci-seconds.
|
||||
*/
|
||||
|
||||
#include "SevSeg.h"
|
||||
SevSeg sevseg; //Instantiate a seven segment controller object
|
||||
|
||||
void setup() {
|
||||
byte numDigits = 4;
|
||||
byte digitPins[] = {2, 3, 4, 5};
|
||||
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
|
||||
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
|
||||
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
|
||||
bool updateWithDelays = false; // Default. Recommended
|
||||
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
|
||||
|
||||
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
|
||||
sevseg.setBrightness(10);
|
||||
pinMode(A5, INPUT_PULLUP);
|
||||
pinMode(A1, INPUT_PULLUP);
|
||||
// Serial.begin(9600); // debugging
|
||||
}
|
||||
float lastReset = 0.0;
|
||||
void loop() {
|
||||
unsigned long runMillis= millis();
|
||||
float actualDays = runMillis/86400000.0;
|
||||
float days = actualDays - lastReset;
|
||||
sevseg.setNumber(days, 3);
|
||||
sevseg.refreshDisplay(); // Must run repeatedly
|
||||
// Serial.println(actualDays,5); // debugging
|
||||
// Serial.println(digitalRead(A1)); // debugging
|
||||
if(!digitalRead(A5)){
|
||||
lastReset = actualDays;
|
||||
}
|
||||
if(!digitalRead(A1)){
|
||||
lastReset = actualDays;
|
||||
}
|
||||
}
|
||||
|
||||
/// END ///
|
62
projects/CountUp/TrumpCountUp.ino
Normal file
62
projects/CountUp/TrumpCountUp.ino
Normal file
@ -0,0 +1,62 @@
|
||||
/* SevSeg Counter Example
|
||||
|
||||
Copyright 2017 Dean Reading
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
This example demonstrates a very simple use of the SevSeg library with a 4
|
||||
digit display. It displays a counter that counts up, showing deci-seconds.
|
||||
*/
|
||||
|
||||
#include "SevSeg.h"
|
||||
SevSeg sevseg; //Instantiate a seven segment controller object
|
||||
|
||||
void setup() {
|
||||
byte numDigits = 4;
|
||||
byte digitPins[] = {2, 3, 4, 5};
|
||||
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
|
||||
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
|
||||
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
|
||||
bool updateWithDelays = false; // Default. Recommended
|
||||
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
|
||||
|
||||
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
|
||||
sevseg.setBrightness(10);
|
||||
pinMode(A5, INPUT_PULLUP);
|
||||
pinMode(A1, INPUT_PULLUP);
|
||||
// Serial.begin(9600); // debugging
|
||||
}
|
||||
|
||||
int decPlaces = 3;
|
||||
float lastReset = 0; // optional button reset - orange wire connected to A1, or programmable button on A5
|
||||
|
||||
void loop() {
|
||||
unsigned long runMillis= millis();
|
||||
float actualDays = runMillis/86400000.0;
|
||||
float days = actualDays - lastReset;
|
||||
sevseg.setNumber(days, decPlaces);
|
||||
sevseg.refreshDisplay(); // Must run repeatedly
|
||||
// Serial.println(actualDays,5); // debugging
|
||||
// Serial.println(digitalRead(A1)); // debugging
|
||||
if(!digitalRead(A1)){lastReset -= 0.001;}
|
||||
// if(!digitalRead(A5)){lastReset = actualDays;}
|
||||
// program A5 as decimal place changer
|
||||
if(!digitalRead(A5)){
|
||||
// if(decPlaces == 2){decPlaces = 3;}
|
||||
// if(decPlaces == 3){decPlaces = 2;}
|
||||
decPlaces = (decPlaces + 1)%2 + 2;
|
||||
delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
/// END ///
|
162
projects/Workstation/Workstation.ino
Normal file
162
projects/Workstation/Workstation.ino
Normal file
@ -0,0 +1,162 @@
|
||||
//YWROBOT
|
||||
//Compatible with the Arduino IDE 1.0
|
||||
//Library version:1.1
|
||||
#include <Wire.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
#include <TM1638.h>
|
||||
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
|
||||
TM1638 module(3, 2, 4);
|
||||
#define NO_MODULES 1
|
||||
TM1638* modules[NO_MODULES] = {
|
||||
&module
|
||||
};
|
||||
byte modes[NO_MODULES];
|
||||
unsigned long trump_reset;
|
||||
unsigned long startTime;
|
||||
unsigned long study_reset;
|
||||
|
||||
const int buttondelay = 150; // millis delay for button bounceback
|
||||
const int backlight_pin = 7;
|
||||
const int rPin = 10; // RGB pins
|
||||
const int gPin = 9;
|
||||
const int bPin = 8;
|
||||
int rval = 0;
|
||||
int gval = 0;
|
||||
int bval = 0;
|
||||
bool backlight_status = 1;
|
||||
int daysSinceLastReset = 0;
|
||||
int studySessions = 0;
|
||||
|
||||
|
||||
void update(TM1638* module, byte* mode) {
|
||||
byte buttons = module->getButtons();
|
||||
unsigned long runningSecs = (millis() - startTime) / 1000;
|
||||
float studyMins = (millis() - study_reset) / (1000.0*60);
|
||||
float trumpDays = (millis() - trump_reset) / (1000.0*60*60*24);
|
||||
|
||||
if(module->getButtons() == 128 ){
|
||||
backlight_status = !backlight_status;
|
||||
digitalWrite(backlight_pin, backlight_status);
|
||||
delay(buttondelay);
|
||||
// module->clearDisplay();
|
||||
}
|
||||
|
||||
// button pressed - change mode
|
||||
if (buttons != 0) {
|
||||
*mode = buttons;
|
||||
}
|
||||
|
||||
// STUDY TIMER ON LCD
|
||||
lcd.setCursor(6,3);
|
||||
lcd.print(int(studyMins));
|
||||
lcd.setCursor(3,3);
|
||||
lcd.print(studySessions);
|
||||
lcd.setCursor(0,3);
|
||||
lcd.print(daysSinceLastReset);
|
||||
|
||||
module->setLEDs(*mode);
|
||||
switch (*mode) {
|
||||
|
||||
case 1 << 0: // STUDY TIMER SUMMARY
|
||||
char s[8];
|
||||
studySessions = int(studyMins/90);
|
||||
daysSinceLastReset = studySessions%16;
|
||||
sprintf(s, "%2d.%2d.%2d", daysSinceLastReset, studySessions, int(studyMins)%90 );
|
||||
module->setDisplayToString(s);
|
||||
break;
|
||||
|
||||
case 1 << 1:
|
||||
module->setDisplayToDecNumber(10000*studyMins, 1 << 4, false);
|
||||
break;
|
||||
|
||||
case 1 << 2:
|
||||
module->setDisplayToDecNumber(1000000*trumpDays, 1 << 6, false);
|
||||
break;
|
||||
|
||||
case 1 << 3:
|
||||
module->setDisplayToDecNumber(runningSecs, 1 << 5, false);
|
||||
break;
|
||||
|
||||
case 1 << 4: // Button 5
|
||||
module->clearDisplay();
|
||||
module->clearDisplayDigit((runningSecs - 1) % 8, 0);
|
||||
module->setDisplayDigit(runningSecs % 8, runningSecs % 8, 0);
|
||||
break;
|
||||
|
||||
case 1 << 5: // reset study timer
|
||||
study_reset = millis();
|
||||
*mode = 1 << 1;
|
||||
delay(buttondelay);
|
||||
module->clearDisplay();
|
||||
break;
|
||||
|
||||
case 1 << 6: // reset trump timer
|
||||
trump_reset = millis();
|
||||
*mode = 1 << 2;
|
||||
delay(buttondelay);
|
||||
module->clearDisplay();
|
||||
break;
|
||||
|
||||
case 1 << 7: // Button 8, reset backlight
|
||||
module->clearDisplay();
|
||||
break;
|
||||
|
||||
case 65:
|
||||
module->setDisplayToError();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
for (int i = 0; i < NO_MODULES; i++) {
|
||||
modules[i]->setupDisplay(true, 7);
|
||||
modes[i] = 0;
|
||||
}
|
||||
|
||||
startTime = millis();
|
||||
study_reset = millis();
|
||||
trump_reset = millis();
|
||||
|
||||
lcd.init(); // initialize the lcd
|
||||
pinMode(backlight_pin, OUTPUT);
|
||||
digitalWrite(backlight_pin, backlight_status);
|
||||
// Print a message to the LCD.
|
||||
|
||||
lcd.backlight();
|
||||
lcd.setCursor(2,0);
|
||||
lcd.print("ACTION EXPRESSES");
|
||||
lcd.setCursor(6,1);
|
||||
lcd.print("PRIORITY.");
|
||||
lcd.setCursor(15,2);
|
||||
lcd.print("ABK");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
for (int i = 0; i < NO_MODULES; i++) {
|
||||
update(modules[i], &modes[i]);
|
||||
}
|
||||
// RGB LED
|
||||
rval = max( rval + rand()%3 - 1, 0); // markov chain
|
||||
gval = max( gval + rand()%3 - 1, 0);
|
||||
bval = max( bval + rand()%3 - 1, 0);
|
||||
rval = min(rval, 255);
|
||||
gval = min(gval, 255);
|
||||
bval = min(bval, 255);
|
||||
|
||||
lcd.setCursor(10,2);
|
||||
lcd.print(rval);
|
||||
digitalWrite(rPin, 0.6*rval);
|
||||
lcd.setCursor(5,2);
|
||||
lcd.print(gval);
|
||||
digitalWrite(gPin, 0.3*gval);
|
||||
lcd.setCursor(0,2);
|
||||
digitalWrite(bPin, 0.1*bval);
|
||||
lcd.print(bval);
|
||||
}
|
347
projects/_4to7pins/_4to7pins.ino
Normal file
347
projects/_4to7pins/_4to7pins.ino
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
This Arduino code for "4-digit-7-segment-led-display" (KYX-5461AS).
|
||||
* This code can display one Number in all 4 digit!
|
||||
* This code can display 4 Numbers each on in specific digit
|
||||
* This code can also make a Number Countdown (Timers).
|
||||
|
||||
author : Oussama Amri (@amriunix)
|
||||
website : ithepro.com
|
||||
*/
|
||||
|
||||
//display pins
|
||||
int segA = 5; // >> 11
|
||||
int segB = 13; // >> 7
|
||||
int segC = 10; // >> 4
|
||||
int segD = 8; // >> 2
|
||||
int segE = 7; // >> 1
|
||||
int segF = 4; // >> 10
|
||||
int segG = 11; // >> 5
|
||||
int segPt = 9; // >> 3
|
||||
//------------//
|
||||
|
||||
//display digit
|
||||
int d1 = 6; // >> 12
|
||||
int d2 = 3; // >> 9
|
||||
int d3 = 2; // >> 8
|
||||
int d4 = 12; // >> 6
|
||||
//------------//
|
||||
|
||||
int delayTime = 5000; //delayTime <Don't change it, if you don't know where is it!>
|
||||
int mydelay = 3000; // 50 is about one second, 3000 a minute
|
||||
int i=0;
|
||||
|
||||
//=============================================//
|
||||
//init all pin used
|
||||
void setup() {
|
||||
pinMode(2, OUTPUT);
|
||||
pinMode(3, OUTPUT);
|
||||
pinMode(4, OUTPUT);
|
||||
pinMode(5, OUTPUT);
|
||||
pinMode(6, OUTPUT);
|
||||
pinMode(7, OUTPUT);
|
||||
pinMode(8, OUTPUT);
|
||||
pinMode(9, OUTPUT);
|
||||
pinMode(10, OUTPUT);
|
||||
pinMode(11, OUTPUT);
|
||||
pinMode(12, OUTPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================//
|
||||
void loop() {
|
||||
downup(0,20,9,0); // numbers above 19 display as blank.
|
||||
//all(8);
|
||||
//writeN(1,9,0,4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================//
|
||||
//Write a Number - writeN(1,9,9,0) -> 1990
|
||||
void writeN(int a,int b,int c,int d){
|
||||
selectDwriteL(1,a);
|
||||
selectDwriteL(2,b);
|
||||
selectDwriteL(3,c);
|
||||
selectDwriteL(4,d);
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
//Make a Number Number Countdown (Timers).
|
||||
void downup(int a,int b,int c,int d){
|
||||
while (a != -1) {
|
||||
while(b != -1){
|
||||
while(c != -1){
|
||||
while (d != -1) {
|
||||
while (i<mydelay) { // i here is like a timer ! because we can't use delay function
|
||||
selectDwriteL(1,a);
|
||||
selectDwriteL(2,b);
|
||||
selectDwriteL(3,c);
|
||||
selectDwriteL(4,d);
|
||||
i++;
|
||||
}
|
||||
i=0;
|
||||
d--;
|
||||
}
|
||||
d=9;
|
||||
c--;
|
||||
}
|
||||
c=9;
|
||||
a++; // iterate the first digit to count up while the last two digits count down.
|
||||
//b--; // this uncommented leaves the second digit blank
|
||||
}
|
||||
a=9;
|
||||
//a++;
|
||||
//a--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================//
|
||||
//Make a Number Number Countdown (Timers).
|
||||
void down(int a,int b,int c,int d){
|
||||
while (a != -1) {
|
||||
while(b != -1){
|
||||
while(c != -1){
|
||||
while (d != -1) {
|
||||
while (i<mydelay) { // i here is like a timer ! because we can't use delay function
|
||||
selectDwriteL(1,a);
|
||||
selectDwriteL(2,b);
|
||||
selectDwriteL(3,c);
|
||||
selectDwriteL(4,d);
|
||||
i++;
|
||||
}
|
||||
i=0;
|
||||
d--;
|
||||
}
|
||||
d=9;
|
||||
c--;
|
||||
}
|
||||
c=9;
|
||||
b--;
|
||||
}
|
||||
b=9;
|
||||
a--;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
//Select Wich Digit (selectD) is going to Display (writeL)
|
||||
void selectDwriteL(int d,int l){
|
||||
switch (d) { // choose a digit
|
||||
case 0: digitalWrite(d1, LOW); //case 0 - All ON
|
||||
digitalWrite(d2, LOW);
|
||||
digitalWrite(d3, LOW);
|
||||
digitalWrite(d4, LOW);
|
||||
break;
|
||||
case 1: digitalWrite(d1, LOW);//case 1 - Digit Number 1
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
case 2: digitalWrite(d1, HIGH);//case 1 - Digit Number 2
|
||||
digitalWrite(d2, LOW);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
case 3: digitalWrite(d1, HIGH);//case 1 - Digit Number 3
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, LOW);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
case 4: digitalWrite(d1, HIGH);//case 1 - Digit Number 4
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, LOW);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (l) { // choose a Number
|
||||
case 0: zero();
|
||||
break;
|
||||
case 1: one();
|
||||
break;
|
||||
case 2: two();
|
||||
break;
|
||||
case 3: three();
|
||||
break;
|
||||
case 4: four();
|
||||
break;
|
||||
case 5: five();
|
||||
break;
|
||||
case 6: six();
|
||||
break;
|
||||
case 7: seven();
|
||||
break;
|
||||
case 8: eight();
|
||||
break;
|
||||
case 9: nine();
|
||||
break;
|
||||
case 10: point(); // print a Point
|
||||
break;
|
||||
case 11: one(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 12: two(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 13: three(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 14: four(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 15: five(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 16: six(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 17: seven(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 18: eight(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 19: nine(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
default: none(); // make all them off !
|
||||
break;
|
||||
}
|
||||
|
||||
delayMicroseconds(delayTime); // delayTime for nice display of the Number !
|
||||
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
//shown one Number in the 4 Digit
|
||||
void all(int n){
|
||||
selectDwriteL(0,n);
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
void zero(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void one(){
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void two(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, LOW);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void three(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void four(){
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void five(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void six(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void seven(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void eight(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void nine(){
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void point(){
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, LOW);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, HIGH);
|
||||
}
|
||||
//=============================================//
|
||||
void none(){
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, LOW);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
|
430
projects/controlLED/controlLED.ino
Normal file
430
projects/controlLED/controlLED.ino
Normal file
@ -0,0 +1,430 @@
|
||||
|
||||
|
||||
#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.h"
|
||||
#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.cpp"
|
||||
|
||||
// PIN FOR RECEIVER
|
||||
int receiver = 3; // Signal Pin of IR receiver to Arduino Digital Pin 11
|
||||
|
||||
/*-----( Declare objects )-----*/
|
||||
IRrecv irrecv(receiver); // create instance of 'irrecv'
|
||||
decode_results results; // create instance of 'decode_results'
|
||||
|
||||
/*-----( Function )-----*/
|
||||
void translateIR() // takes action based on IR code received
|
||||
|
||||
// describing Remote IR codes
|
||||
|
||||
{
|
||||
|
||||
switch (results.value)
|
||||
{
|
||||
case 0xFFA25D: Serial.println("POWER"); off(); break;
|
||||
case 0xFFE21D: Serial.println("FUNC/STOP"); break;
|
||||
case 0xFF629D: Serial.println("VOL+"); break;
|
||||
case 0xFF22DD: Serial.println("FAST BACK"); break;
|
||||
case 0xFF02FD: Serial.println("PAUSE"); break;
|
||||
case 0xFFC23D: Serial.println("FAST FORWARD"); break;
|
||||
case 0xFFE01F: Serial.println("DOWN"); break;
|
||||
case 0xFFA857: Serial.println("VOL-"); break;
|
||||
case 0xFF906F: Serial.println("UP"); break;
|
||||
case 0xFF9867: Serial.println("EQ"); downup(6, 9, 0); off(); break;
|
||||
case 0xFFB04F: Serial.println("ST/REPT"); downup(0, 9, 0); off(); break;
|
||||
case 0xFF6897: Serial.println("0"); all(0); break;
|
||||
case 0xFF30CF: Serial.println("1"); all(1); break;
|
||||
case 0xFF18E7: Serial.println("2"); all(2); break;
|
||||
case 0xFF7A85: Serial.println("3"); all(3); break;
|
||||
case 0xFF10EF: Serial.println("4"); all(4); break;
|
||||
case 0xFF38C7: Serial.println("5"); all(5); break;
|
||||
case 0xFF5AA5: Serial.println("6"); all(6); break;
|
||||
case 0xFF42BD: Serial.println("7"); all(7); break;
|
||||
case 0xFF4AB5: Serial.println("8"); all(8); break;
|
||||
case 0xFF52AD: Serial.println("9"); all(9); break;
|
||||
case 0xFFFFFFFF: Serial.println(" REPEAT"); break;
|
||||
|
||||
default:
|
||||
Serial.println(" other button ");
|
||||
|
||||
}// End Case
|
||||
|
||||
delay(1000); // Do not get immediate repeat
|
||||
|
||||
|
||||
} //END translateIR
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
//display pins
|
||||
int segA = 5; // >> 11
|
||||
int segB = 13; // >> 7
|
||||
int segC = 10; // >> 4
|
||||
int segD = 8; // >> 2
|
||||
int segE = 7; // >> 1
|
||||
int segF = 4; // >> 10
|
||||
int segG = 11; // >> 5
|
||||
int segPt = 9; // >> 3
|
||||
//------------//
|
||||
|
||||
//display digit
|
||||
int d1 = 6; // >> 12
|
||||
int d2 = 3; // >> 9
|
||||
int d3 = 2; // >> 8
|
||||
int d4 = 12; // >> 6
|
||||
//------------//
|
||||
|
||||
int delayTime = 5000; //delayTime <Don't change it, if you don't know where is it!>
|
||||
int mydelay = 3000; // 50 is about one second, 3000 a minute
|
||||
int i = 0;
|
||||
|
||||
//=============================================//
|
||||
//init all pin used
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("IR Receiver Button Decode - Initializing...");
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
|
||||
pinMode(2, OUTPUT);
|
||||
// pinMode(3, OUTPUT); // reserved for IR input
|
||||
pinMode(4, OUTPUT);
|
||||
pinMode(5, OUTPUT);
|
||||
pinMode(6, OUTPUT);
|
||||
pinMode(7, OUTPUT);
|
||||
pinMode(8, OUTPUT);
|
||||
pinMode(9, OUTPUT);
|
||||
pinMode(10, OUTPUT);
|
||||
pinMode(11, OUTPUT);
|
||||
pinMode(12, OUTPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================================//
|
||||
//void loop() {
|
||||
//downup(0,20,9,0); // numbers above 19 display as blank.
|
||||
////all(8);
|
||||
////writeN(1,9,0,4);
|
||||
//}
|
||||
void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
|
||||
{
|
||||
if (irrecv.decode(&results)) // have we received an IR signal?
|
||||
{
|
||||
// Serial.println(results.value); // for debugging
|
||||
translateIR();
|
||||
irrecv.resume(); // receive the next value
|
||||
}
|
||||
|
||||
}/* --(end main loop )-- */
|
||||
|
||||
|
||||
//=======================================================================================//
|
||||
//Write a Number - writeN(1,9,9,0) -> 1990
|
||||
void writeN(int a, int b, int c, int d) {
|
||||
selectDwriteL(1, a);
|
||||
selectDwriteL(2, b);
|
||||
selectDwriteL(3, c);
|
||||
selectDwriteL(4, d);
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
//Make a Number Number Countdown (Timers).
|
||||
void downup(int A, int C, int D) {
|
||||
irrecv.resume();
|
||||
int a=0;
|
||||
int c, d;
|
||||
bool FLAG = 0;
|
||||
while (a <= A) {
|
||||
c = C;
|
||||
d = D;
|
||||
while (c != -1) {
|
||||
while (d != -1) {
|
||||
while (i < mydelay) { // i here is like a timer ! because we can't use delay function
|
||||
selectDwriteL(1, a);
|
||||
selectDwriteL(3, c);
|
||||
selectDwriteL(4, d);
|
||||
if (irrecv.decode(&results)) // have we received an IR signal?
|
||||
{
|
||||
// if(results.value == 16753245){
|
||||
translateIR();
|
||||
FLAG = 1;
|
||||
// break;
|
||||
irrecv.resume(); // receive the next value
|
||||
// }
|
||||
}
|
||||
i++;
|
||||
if(FLAG){d=0;a=A;c=0;i=mydelay;}
|
||||
}
|
||||
i = 0;
|
||||
d--;
|
||||
}
|
||||
d = 9;
|
||||
c--;
|
||||
}
|
||||
// c = 9; // third digit
|
||||
a++; // iterate the first digit to count up while the last two digits count down.
|
||||
//b--; // this uncommented leaves the second digit blank
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================//
|
||||
//Make a Number Number Countdown (Timers).
|
||||
void down(int a, int b, int c, int d) {
|
||||
while (a != -1) {
|
||||
while (b != -1) {
|
||||
while (c != -1) {
|
||||
while (d != -1) {
|
||||
while (i < mydelay) { // i here is like a timer ! because we can't use delay function
|
||||
selectDwriteL(1, a);
|
||||
selectDwriteL(2, b);
|
||||
selectDwriteL(3, c);
|
||||
selectDwriteL(4, d);
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
d--;
|
||||
}
|
||||
d = 9;
|
||||
c--;
|
||||
}
|
||||
c = 9;
|
||||
b--;
|
||||
}
|
||||
b = 9;
|
||||
a--;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
//Select Which Digit (selectD) is going to Display (writeL)
|
||||
void selectDwriteL(int d, int l) {
|
||||
switch (d) { // choose a digit
|
||||
case 0: digitalWrite(d1, LOW); //case 0 - All ON
|
||||
digitalWrite(d2, LOW);
|
||||
digitalWrite(d3, LOW);
|
||||
digitalWrite(d4, LOW);
|
||||
break;
|
||||
case 1: digitalWrite(d1, LOW);//case 1 - Digit Number 1
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
case 2: digitalWrite(d1, HIGH);//case 1 - Digit Number 2
|
||||
digitalWrite(d2, LOW);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
case 3: digitalWrite(d1, HIGH);//case 1 - Digit Number 3
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, LOW);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
case 4: digitalWrite(d1, HIGH);//case 1 - Digit Number 4
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, LOW);
|
||||
break;
|
||||
case 5: digitalWrite(d1, HIGH); //case 0 - All ON
|
||||
digitalWrite(d2, HIGH);
|
||||
digitalWrite(d3, HIGH);
|
||||
digitalWrite(d4, HIGH);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (l) { // choose a Number
|
||||
case 0: zero();
|
||||
break;
|
||||
case 1: one();
|
||||
break;
|
||||
case 2: two();
|
||||
break;
|
||||
case 3: three();
|
||||
break;
|
||||
case 4: four();
|
||||
break;
|
||||
case 5: five();
|
||||
break;
|
||||
case 6: six();
|
||||
break;
|
||||
case 7: seven();
|
||||
break;
|
||||
case 8: eight();
|
||||
break;
|
||||
case 9: nine();
|
||||
break;
|
||||
case 10: point(); // print a Point
|
||||
break;
|
||||
case 11: one(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 12: two(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 13: three(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 14: four(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 15: five(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 16: six(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 17: seven(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 18: eight(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case 19: nine(); digitalWrite(segPt, HIGH);
|
||||
break;
|
||||
case -1: none();
|
||||
break;
|
||||
default: none(); // make all them off !
|
||||
break;
|
||||
}
|
||||
|
||||
delayMicroseconds(delayTime); // delayTime for nice display of the Number !
|
||||
|
||||
}
|
||||
|
||||
//=============================================//
|
||||
//shown one Number in the 4 Digit
|
||||
void all(int n) {
|
||||
selectDwriteL(0, n);
|
||||
}
|
||||
|
||||
void off() {
|
||||
selectDwriteL(5, 0);
|
||||
}
|
||||
|
||||
|
||||
//=============================================//
|
||||
void zero() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void one() {
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void two() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, LOW);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void three() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void four() {
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void five() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void six() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void seven() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void eight() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, HIGH);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void nine() {
|
||||
digitalWrite(segA, HIGH);
|
||||
digitalWrite(segB, HIGH);
|
||||
digitalWrite(segC, HIGH);
|
||||
digitalWrite(segD, HIGH);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, HIGH);
|
||||
digitalWrite(segG, HIGH);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
//=============================================//
|
||||
void point() {
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, LOW);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, HIGH);
|
||||
}
|
||||
//=============================================//
|
||||
void none() {
|
||||
digitalWrite(segA, LOW);
|
||||
digitalWrite(segB, LOW);
|
||||
digitalWrite(segC, LOW);
|
||||
digitalWrite(segD, LOW);
|
||||
digitalWrite(segE, LOW);
|
||||
digitalWrite(segF, LOW);
|
||||
digitalWrite(segG, LOW);
|
||||
digitalWrite(segPt, LOW);
|
||||
}
|
||||
|
100
projects/controlservo/controlservo.ino
Normal file
100
projects/controlservo/controlservo.ino
Normal file
@ -0,0 +1,100 @@
|
||||
#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.h"
|
||||
#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.cpp"
|
||||
#include <Servo.h>
|
||||
|
||||
// PIN FOR RECEIVER
|
||||
int receiver = 3; // Signal Pin of IR receiver to Arduino Digital Pin 11
|
||||
int pos = 0; // variable to store the servo position
|
||||
|
||||
/*-----( Declare objects )-----*/
|
||||
IRrecv irrecv(receiver); // create instance of 'irrecv'
|
||||
decode_results results; // create instance of 'decode_results'
|
||||
Servo myservo; // create servo object to control a servo
|
||||
|
||||
/*-----( Function )-----*/
|
||||
void translateIR() // takes action based on IR code received
|
||||
|
||||
// describing Remote IR codes
|
||||
|
||||
{
|
||||
|
||||
switch (results.value)
|
||||
{
|
||||
case 0xFFA25D: Serial.println("POWER"); myservo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
break;
|
||||
case 0xFFE21D: Serial.println("FUNC/STOP"); myservo.detach(); // attaches the servo on pin 9 to the servo object
|
||||
break;
|
||||
case 0xFF629D: Serial.println("VOL+"); digitalWrite(8, HIGH); break;
|
||||
case 0xFF22DD: Serial.println("FAST BACK"); break;
|
||||
case 0xFF02FD: Serial.println("PAUSE"); break;
|
||||
case 0xFFC23D: Serial.println("FAST FORWARD"); break;
|
||||
case 0xFFE01F: Serial.println("DOWN"); for (pos = 5; pos >=0; pos-=1){myservo.attach(9); myservo.write(pos); delay(15); myservo.detach();} break;
|
||||
case 0xFFA857: Serial.println("VOL-"); digitalWrite(8, LOW); break;
|
||||
case 0xFF906F: Serial.println("UP"); for (pos = 0; pos <=5; pos+=1){myservo.attach(9); myservo.write(pos); delay(15); myservo.detach();} break;
|
||||
case 0xFF9867: Serial.println("EQ"); break;
|
||||
case 0xFFB04F: Serial.println("ST/REPT"); break;
|
||||
case 0xFF6897: Serial.println("0"); break;
|
||||
case 0xFF30CF: Serial.println("1"); break;
|
||||
case 0xFF18E7: Serial.println("2"); break;
|
||||
case 0xFF7A85: Serial.println("3");; break;
|
||||
case 0xFF10EF: Serial.println("4"); break;
|
||||
case 0xFF38C7: Serial.println("5"); break;
|
||||
case 0xFF5AA5: Serial.println("6"); break;
|
||||
case 0xFF42BD: Serial.println("7"); break;
|
||||
case 0xFF4AB5: Serial.println("8"); break;
|
||||
case 0xFF52AD: Serial.println("9"); break;
|
||||
//case 0xFFFFFFFF: Serial.println(" REPEAT"); digitalWrite(8, LOW); break;
|
||||
|
||||
default:
|
||||
Serial.println(" other button ");
|
||||
|
||||
}// End Case
|
||||
|
||||
delay(50); // Do not get immediate repeat
|
||||
|
||||
|
||||
} //END translateIR
|
||||
|
||||
|
||||
|
||||
//=============================================//
|
||||
//init all pin used
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("IR Receiver Button Decode - Initializing...");
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
|
||||
pinMode(2, OUTPUT);
|
||||
// pinMode(3, OUTPUT); // reserved for IR input
|
||||
// pinMode(4, OUTPUT);
|
||||
// pinMode(5, OUTPUT);
|
||||
// pinMode(6, OUTPUT);
|
||||
// pinMode(7, OUTPUT);
|
||||
pinMode(8, OUTPUT);
|
||||
pinMode(9, OUTPUT);
|
||||
myservo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
// pinMode(10, OUTPUT);
|
||||
// pinMode(11, OUTPUT);
|
||||
// pinMode(12, OUTPUT);
|
||||
// pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================================//
|
||||
void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
|
||||
{
|
||||
if (irrecv.decode(&results)) // have we received an IR signal?
|
||||
{
|
||||
// Serial.println(results.value); // for debugging
|
||||
translateIR();
|
||||
irrecv.resume(); // receive the next value
|
||||
|
||||
}
|
||||
|
||||
}/* --(end main loop )-- */
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
projects/elegoo-kit-lessons/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Elegoo Super Starter Kit for UNO V1.0.2017.7.9.pdf
Executable file
BIN
projects/elegoo-kit-lessons/Elegoo Super Starter Kit for UNO V1.0.2017.7.9.pdf
Executable file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Lesson 10 Ultrasonic Sensor Module/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 10 Ultrasonic Sensor Module/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Lesson 10 Ultrasonic Sensor Module/HC-SR04.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 10 Ultrasonic Sensor Module/HC-SR04.zip
Executable file
Binary file not shown.
@ -0,0 +1,21 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.08
|
||||
#include "SR04.h"
|
||||
#define TRIG_PIN 12
|
||||
#define ECHO_PIN 11
|
||||
SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);
|
||||
long a;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
a=sr04.Distance();
|
||||
if(a>0){
|
||||
Serial.print(a);
|
||||
Serial.println("cm");
|
||||
}
|
||||
delay(10);
|
||||
}
|
BIN
projects/elegoo-kit-lessons/Lesson 11 DHT11 Temperature and Humidity Sensor/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 11 DHT11 Temperature and Humidity Sensor/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Lesson 11 DHT11 Temperature and Humidity Sensor/DHT11/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 11 DHT11 Temperature and Humidity Sensor/DHT11/.DS_Store
vendored
Normal file
Binary file not shown.
@ -0,0 +1,121 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
#include <SimpleDHT.h>
|
||||
#include <avr/sleep.h>
|
||||
// for DHT11,
|
||||
// VCC: 5V or 3V
|
||||
// GND: GND
|
||||
// DATA: 2
|
||||
int pinDHT11 = 2;
|
||||
SimpleDHT11 dht11;
|
||||
|
||||
void blink(int delayTime) {
|
||||
digitalWrite(13, HIGH);
|
||||
delay(delayTime);
|
||||
digitalWrite(13, LOW);
|
||||
delay(delayTime);
|
||||
}
|
||||
|
||||
void change(){
|
||||
delay(500);
|
||||
blink(1000);
|
||||
delay(500);
|
||||
}
|
||||
int ct = 0;
|
||||
int SerialTransmit = 1;
|
||||
int pin2_interrupt_flag = 0;
|
||||
|
||||
void pin2_isr()
|
||||
{
|
||||
sleep_disable();
|
||||
detachInterrupt(0);
|
||||
pin2_interrupt_flag = 1;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
if(SerialTransmit){Serial.begin(9600);}
|
||||
pinMode(13,OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// start working...
|
||||
|
||||
// sleep_enable();
|
||||
// attachInterrupt(0, pin2_isr, LOW);
|
||||
/* 0, 1, or many lines of code here */
|
||||
|
||||
|
||||
if(SerialTransmit){
|
||||
Serial.println("=================================");
|
||||
Serial.println("Sample DHT11...");
|
||||
}
|
||||
byte temperature = 0;
|
||||
byte humidity = 0;
|
||||
byte data[40] = {0};
|
||||
// read with raw sample data
|
||||
if(ct >= 0){
|
||||
dht11.read(pinDHT11, &temperature, &humidity, data);
|
||||
ct++;
|
||||
|
||||
// TEMPERATURE
|
||||
for (int i = 0; i < (int)temperature/100; i++){
|
||||
blink(50);
|
||||
}
|
||||
|
||||
change();
|
||||
for (int i = 0; i < (int)temperature/10; i++){
|
||||
blink(50);
|
||||
}
|
||||
|
||||
change();
|
||||
for (int i = 0; i < (int)temperature%10; i++){
|
||||
blink(50);
|
||||
}
|
||||
|
||||
// HUMIDITY
|
||||
change();
|
||||
for (int i = 0; i < (int)humidity/10; i++){
|
||||
blink(50);
|
||||
}
|
||||
|
||||
change();
|
||||
for (int i = 0; i < (int)humidity%10; i++){
|
||||
blink(50);
|
||||
}
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
|
||||
|
||||
if(SerialTransmit){
|
||||
if (dht11.read(pinDHT11, &temperature, &humidity, data)) {
|
||||
Serial.print("Read DHT11 failed");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Sample RAW Bits: ");
|
||||
for (int i = 0; i < 40; i++) {
|
||||
Serial.print((int)data[i]);
|
||||
if (i > 0 && ((i + 1) % 4) == 0) {
|
||||
Serial.print(' ');
|
||||
}
|
||||
}
|
||||
Serial.println("");
|
||||
|
||||
Serial.print("Sample OK: ");
|
||||
Serial.print((int)temperature); Serial.print(" *C, ");
|
||||
Serial.print((int)humidity); Serial.println(" %");
|
||||
|
||||
// DHT11 sampling rate is 1HZ.
|
||||
delay(1000);
|
||||
}
|
||||
// set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
// cli();
|
||||
// sleep_bod_disable();
|
||||
// sei();
|
||||
// sleep_cpu();
|
||||
// /* wake up here */
|
||||
// sleep_disable();
|
||||
// ct = 0;
|
||||
}
|
Binary file not shown.
@ -0,0 +1,26 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.09
|
||||
|
||||
// Arduino pin numbers
|
||||
const int SW_pin = 2; // digital pin connected to switch output
|
||||
const int X_pin = 0; // analog pin connected to X output
|
||||
const int Y_pin = 1; // analog pin connected to Y output
|
||||
|
||||
void setup() {
|
||||
pinMode(SW_pin, INPUT);
|
||||
digitalWrite(SW_pin, HIGH);
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("Switch: ");
|
||||
Serial.print(digitalRead(SW_pin));
|
||||
Serial.print("\n");
|
||||
Serial.print("X-axis: ");
|
||||
Serial.print(analogRead(X_pin));
|
||||
Serial.print("\n");
|
||||
Serial.print("Y-axis: ");
|
||||
Serial.println(analogRead(Y_pin));
|
||||
Serial.print("\n\n");
|
||||
delay(500);
|
||||
}
|
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IR_Receiver_Module/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IR_Receiver_Module/.DS_Store
vendored
Normal file
Binary file not shown.
@ -0,0 +1,77 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.h"
|
||||
#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.cpp"
|
||||
//#include "/Users/Imogen/Documents/Arduino/libraries/IRremote/IRremoteInt.h"
|
||||
int LEDPIN = 8;
|
||||
|
||||
int receiver = 3; // Signal Pin of IR receiver to Arduino Digital Pin 11
|
||||
/*-----( Declare objects )-----*/
|
||||
IRrecv irrecv(receiver); // create instance of 'irrecv'
|
||||
decode_results results; // create instance of 'decode_results'
|
||||
|
||||
/*-----( Function )-----*/
|
||||
void translateIR() // takes action based on IR code received
|
||||
|
||||
// describing Remote IR codes
|
||||
|
||||
{
|
||||
|
||||
switch(results.value)
|
||||
{
|
||||
case 0xFFA25D: Serial.println("POWER"); digitalWrite(LEDPIN, HIGH); break;
|
||||
case 0xFFE21D: Serial.println("FUNC/STOP"); digitalWrite(LEDPIN, LOW); break;
|
||||
case 0xFF629D: Serial.println("VOL+"); break;
|
||||
case 0xFF22DD: Serial.println("FAST BACK"); break;
|
||||
case 0xFF02FD: Serial.println("PAUSE"); break;
|
||||
case 0xFFC23D: Serial.println("FAST FORWARD"); break;
|
||||
case 0xFFE01F: Serial.println("DOWN"); break;
|
||||
case 0xFFA857: Serial.println("VOL-"); break;
|
||||
case 0xFF906F: Serial.println("UP"); break;
|
||||
case 0xFF9867: Serial.println("EQ"); break;
|
||||
case 0xFFB04F: Serial.println("ST/REPT"); break;
|
||||
case 0xFF6897: Serial.println("0"); break;
|
||||
case 0xFF30CF: Serial.println("1"); break;
|
||||
case 0xFF18E7: Serial.println("2"); break;
|
||||
case 0xFF7A85: Serial.println("3"); break;
|
||||
case 0xFF10EF: Serial.println("4"); break;
|
||||
case 0xFF38C7: Serial.println("5"); break;
|
||||
case 0xFF5AA5: Serial.println("6"); break;
|
||||
case 0xFF42BD: Serial.println("7"); break;
|
||||
case 0xFF4AB5: Serial.println("8"); break;
|
||||
case 0xFF52AD: Serial.println("9"); break;
|
||||
//case 0xFFFFFFFF: Serial.println(" REPEAT"); digitalWrite(8, LOW); break;
|
||||
|
||||
default:
|
||||
Serial.println(" other button ");
|
||||
|
||||
}// End Case
|
||||
|
||||
delay(100); // Do not get immediate repeat
|
||||
|
||||
|
||||
} //END translateIR
|
||||
void setup() /*----( SETUP: RUNS ONCE )----*/
|
||||
{
|
||||
Serial.begin(9600);
|
||||
Serial.println("IR Receiver Button Decode - Initializing...");
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
pinMode(LEDPIN, OUTPUT);
|
||||
Serial.println("Done.");
|
||||
|
||||
}/*--(end setup )---*/
|
||||
|
||||
|
||||
void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
|
||||
{
|
||||
if (irrecv.decode(&results)) // have we received an IR signal?
|
||||
|
||||
{
|
||||
translateIR();
|
||||
//Serial.println(results.value);
|
||||
irrecv.resume(); // receive the next value
|
||||
}
|
||||
}/* --(end main loop )-- */
|
||||
|
||||
|
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote.zip
Executable file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/.DS_Store
vendored
Normal file
Binary file not shown.
1154
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/IRremote.cpp
Executable file
1154
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/IRremote.cpp
Executable file
File diff suppressed because it is too large
Load Diff
128
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/IRremote.h
Executable file
128
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/IRremote.h
Executable file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com
|
||||
* Edited by Mitra to add new controller SANYO
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
* LG added by Darryl Smith (based on the JVC protocol)
|
||||
*/
|
||||
|
||||
#ifndef IRremote_h
|
||||
#define IRremote_h
|
||||
|
||||
// The following are compile-time library options.
|
||||
// If you change them, recompile the library.
|
||||
// If DEBUG is defined, a lot of debugging output will be printed during decoding.
|
||||
// TEST must be defined for the IRtest unittests to work. It will make some
|
||||
// methods virtual, which will be slightly slower, which is why it is optional.
|
||||
// #define DEBUG
|
||||
// #define TEST
|
||||
|
||||
// Results returned from the decoder
|
||||
class decode_results {
|
||||
public:
|
||||
int decode_type; // NEC, SONY, RC5, UNKNOWN
|
||||
union { // This is used for decoding Panasonic and Sharp data
|
||||
unsigned int panasonicAddress;
|
||||
unsigned int sharpAddress;
|
||||
};
|
||||
unsigned long value; // Decoded value
|
||||
int bits; // Number of bits in decoded value
|
||||
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||
int rawlen; // Number of records in rawbuf.
|
||||
};
|
||||
|
||||
// Values for decode_type
|
||||
#define NEC 1
|
||||
#define SONY 2
|
||||
#define RC5 3
|
||||
#define RC6 4
|
||||
#define DISH 5
|
||||
#define SHARP 6
|
||||
#define PANASONIC 7
|
||||
#define JVC 8
|
||||
#define SANYO 9
|
||||
#define MITSUBISHI 10
|
||||
#define SAMSUNG 11
|
||||
#define LG 12
|
||||
#define UNKNOWN -1
|
||||
|
||||
// Decoded value for NEC when a repeat code is received
|
||||
#define REPEAT 0xffffffff
|
||||
|
||||
// main class for receiving IR
|
||||
class IRrecv
|
||||
{
|
||||
public:
|
||||
IRrecv(int recvpin);
|
||||
void blink13(int blinkflag);
|
||||
int decode(decode_results *results);
|
||||
void enableIRIn();
|
||||
void resume();
|
||||
private:
|
||||
// These are called by decode
|
||||
int getRClevel(decode_results *results, int *offset, int *used, int t1);
|
||||
long decodeNEC(decode_results *results);
|
||||
long decodeSony(decode_results *results);
|
||||
long decodeSanyo(decode_results *results);
|
||||
long decodeMitsubishi(decode_results *results);
|
||||
long decodeRC5(decode_results *results);
|
||||
long decodeRC6(decode_results *results);
|
||||
long decodePanasonic(decode_results *results);
|
||||
long decodeLG(decode_results *results);
|
||||
long decodeJVC(decode_results *results);
|
||||
long decodeSAMSUNG(decode_results *results);
|
||||
long decodeHash(decode_results *results);
|
||||
int compare(unsigned int oldval, unsigned int newval);
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
// Only used for testing; can remove virtual for shorter code
|
||||
#ifdef TEST
|
||||
#define VIRTUAL virtual
|
||||
#else
|
||||
#define VIRTUAL
|
||||
#endif
|
||||
|
||||
class IRsend
|
||||
{
|
||||
public:
|
||||
IRsend() {}
|
||||
void sendNEC(unsigned long data, int nbits);
|
||||
void sendSony(unsigned long data, int nbits);
|
||||
// Neither Sanyo nor Mitsubishi send is implemented yet
|
||||
// void sendSanyo(unsigned long data, int nbits);
|
||||
// void sendMitsubishi(unsigned long data, int nbits);
|
||||
void sendRaw(unsigned int buf[], int len, int hz);
|
||||
void sendRC5(unsigned long data, int nbits);
|
||||
void sendRC6(unsigned long data, int nbits);
|
||||
void sendDISH(unsigned long data, int nbits);
|
||||
void sendSharp(unsigned int address, unsigned int command);
|
||||
void sendSharpRaw(unsigned long data, int nbits);
|
||||
void sendPanasonic(unsigned int address, unsigned long data);
|
||||
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
|
||||
// private:
|
||||
void sendSAMSUNG(unsigned long data, int nbits);
|
||||
void enableIROut(int khz);
|
||||
VIRTUAL void mark(int usec);
|
||||
VIRTUAL void space(int usec);
|
||||
}
|
||||
;
|
||||
|
||||
// Some useful constants
|
||||
|
||||
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||
#define RAWBUF 100 // Length of raw duration buffer
|
||||
|
||||
// Marks tend to be 100us too long, and spaces 100us too short
|
||||
// when received due to sensor lag.
|
||||
#define MARK_EXCESS 100
|
||||
|
||||
#endif
|
515
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/IRremoteInt.h
Executable file
515
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/IRremoteInt.h
Executable file
@ -0,0 +1,515 @@
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
*
|
||||
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#ifndef IRremoteint_h
|
||||
#define IRremoteint_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
// define which timer to use
|
||||
//
|
||||
// Uncomment the timer you wish to use on your board. If you
|
||||
// are using another library which uses timer2, you have options
|
||||
// to switch IRremote to use a different timer.
|
||||
|
||||
// Arduino Mega
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 11
|
||||
#define IR_USE_TIMER2 // tx = pin 9
|
||||
//#define IR_USE_TIMER3 // tx = pin 5
|
||||
//#define IR_USE_TIMER4 // tx = pin 6
|
||||
//#define IR_USE_TIMER5 // tx = pin 46
|
||||
|
||||
// Teensy 1.0
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define IR_USE_TIMER1 // tx = pin 17
|
||||
|
||||
// Teensy 2.0
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 14
|
||||
//#define IR_USE_TIMER3 // tx = pin 9
|
||||
#define IR_USE_TIMER4_HS // tx = pin 10
|
||||
|
||||
// Teensy 3.0
|
||||
#elif defined(__MK20DX128__)
|
||||
#define IR_USE_TIMER_CMT // tx = pin 5
|
||||
|
||||
// Teensy++ 1.0 & 2.0
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 25
|
||||
#define IR_USE_TIMER2 // tx = pin 1
|
||||
//#define IR_USE_TIMER3 // tx = pin 16
|
||||
|
||||
// Sanguino
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 13
|
||||
#define IR_USE_TIMER2 // tx = pin 14
|
||||
|
||||
// Atmega8
|
||||
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#define IR_USE_TIMER1 // tx = pin 9
|
||||
|
||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||
#else
|
||||
//#define IR_USE_TIMER1 // tx = pin 9
|
||||
#define IR_USE_TIMER2 // tx = pin 3
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef F_CPU
|
||||
#define SYSCLOCK F_CPU // main Arduino clock
|
||||
#else
|
||||
#define SYSCLOCK 16000000 // main Arduino clock
|
||||
#endif
|
||||
|
||||
#define ERR 0
|
||||
#define DECODED 1
|
||||
|
||||
|
||||
// defines for setting and clearing register bits
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
// Pulse parms are *50-100 for the Mark and *50+100 for the space
|
||||
// First MARK is the one after the long gap
|
||||
// pulse parameters in usec
|
||||
#define NEC_HDR_MARK 9000
|
||||
#define NEC_HDR_SPACE 4500
|
||||
#define NEC_BIT_MARK 560
|
||||
#define NEC_ONE_SPACE 1600
|
||||
#define NEC_ZERO_SPACE 560
|
||||
#define NEC_RPT_SPACE 2250
|
||||
|
||||
#define SONY_HDR_MARK 2400
|
||||
#define SONY_HDR_SPACE 600
|
||||
#define SONY_ONE_MARK 1200
|
||||
#define SONY_ZERO_MARK 600
|
||||
#define SONY_RPT_LENGTH 45000
|
||||
#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
|
||||
|
||||
// SA 8650B
|
||||
#define SANYO_HDR_MARK 3500 // seen range 3500
|
||||
#define SANYO_HDR_SPACE 950 // seen 950
|
||||
#define SANYO_ONE_MARK 2400 // seen 2400
|
||||
#define SANYO_ZERO_MARK 700 // seen 700
|
||||
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
#define SANYO_RPT_LENGTH 45000
|
||||
|
||||
// Mitsubishi RM 75501
|
||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
||||
|
||||
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
|
||||
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
|
||||
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
|
||||
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
|
||||
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
// #define MITSUBISHI_RPT_LENGTH 45000
|
||||
|
||||
|
||||
#define RC5_T1 889
|
||||
#define RC5_RPT_LENGTH 46000
|
||||
|
||||
#define RC6_HDR_MARK 2666
|
||||
#define RC6_HDR_SPACE 889
|
||||
#define RC6_T1 444
|
||||
#define RC6_RPT_LENGTH 46000
|
||||
|
||||
#define SHARP_BIT_MARK 245
|
||||
#define SHARP_ONE_SPACE 1805
|
||||
#define SHARP_ZERO_SPACE 795
|
||||
#define SHARP_GAP 600000
|
||||
#define SHARP_TOGGLE_MASK 0x3FF
|
||||
#define SHARP_RPT_SPACE 3000
|
||||
|
||||
#define DISH_HDR_MARK 400
|
||||
#define DISH_HDR_SPACE 6100
|
||||
#define DISH_BIT_MARK 400
|
||||
#define DISH_ONE_SPACE 1700
|
||||
#define DISH_ZERO_SPACE 2800
|
||||
#define DISH_RPT_SPACE 6200
|
||||
#define DISH_TOP_BIT 0x8000
|
||||
|
||||
#define PANASONIC_HDR_MARK 3502
|
||||
#define PANASONIC_HDR_SPACE 1750
|
||||
#define PANASONIC_BIT_MARK 502
|
||||
#define PANASONIC_ONE_SPACE 1244
|
||||
#define PANASONIC_ZERO_SPACE 400
|
||||
|
||||
#define JVC_HDR_MARK 8000
|
||||
#define JVC_HDR_SPACE 4000
|
||||
#define JVC_BIT_MARK 600
|
||||
#define JVC_ONE_SPACE 1600
|
||||
#define JVC_ZERO_SPACE 550
|
||||
#define JVC_RPT_LENGTH 60000
|
||||
|
||||
#define LG_HDR_MARK 8000
|
||||
#define LG_HDR_SPACE 4000
|
||||
#define LG_BIT_MARK 600
|
||||
#define LG_ONE_SPACE 1600
|
||||
#define LG_ZERO_SPACE 550
|
||||
#define LG_RPT_LENGTH 60000
|
||||
|
||||
#define SAMSUNG_HDR_MARK 5000
|
||||
#define SAMSUNG_HDR_SPACE 5000
|
||||
#define SAMSUNG_BIT_MARK 560
|
||||
#define SAMSUNG_ONE_SPACE 1600
|
||||
#define SAMSUNG_ZERO_SPACE 560
|
||||
#define SAMSUNG_RPT_SPACE 2250
|
||||
|
||||
|
||||
#define SHARP_BITS 15
|
||||
#define DISH_BITS 16
|
||||
|
||||
#define TOLERANCE 25 // percent tolerance in measurements
|
||||
#define LTOL (1.0 - TOLERANCE/100.)
|
||||
#define UTOL (1.0 + TOLERANCE/100.)
|
||||
|
||||
#define _GAP 5000 // Minimum map between transmissions
|
||||
#define GAP_TICKS (_GAP/USECPERTICK)
|
||||
|
||||
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
|
||||
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
|
||||
|
||||
// receiver states
|
||||
#define STATE_IDLE 2
|
||||
#define STATE_MARK 3
|
||||
#define STATE_SPACE 4
|
||||
#define STATE_STOP 5
|
||||
|
||||
// information for the interrupt handler
|
||||
typedef struct {
|
||||
uint8_t recvpin; // pin for IR data from detector
|
||||
uint8_t rcvstate; // state machine
|
||||
uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing
|
||||
unsigned int timer; // state timer, counts 50uS ticks.
|
||||
unsigned int rawbuf[RAWBUF]; // raw data
|
||||
uint8_t rawlen; // counter of entries in rawbuf
|
||||
}
|
||||
irparams_t;
|
||||
|
||||
// Defined in IRremote.cpp
|
||||
extern volatile irparams_t irparams;
|
||||
|
||||
// IR detector output is active low
|
||||
#define MARK 0
|
||||
#define SPACE 1
|
||||
|
||||
#define TOPBIT 0x80000000
|
||||
|
||||
#define NEC_BITS 32
|
||||
#define SONY_BITS 12
|
||||
#define SANYO_BITS 12
|
||||
#define MITSUBISHI_BITS 16
|
||||
#define MIN_RC5_SAMPLES 11
|
||||
#define MIN_RC6_SAMPLES 1
|
||||
#define PANASONIC_BITS 48
|
||||
#define JVC_BITS 16
|
||||
#define LG_BITS 28
|
||||
#define SAMSUNG_BITS 32
|
||||
|
||||
|
||||
|
||||
|
||||
// defines for timer2 (8 bits)
|
||||
#if defined(IR_USE_TIMER2)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
||||
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
||||
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR2A = _BV(WGM20); \
|
||||
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
||||
OCR2A = pwmval; \
|
||||
OCR2B = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
||||
#if (TIMER_COUNT_TOP < 256)
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR2A = _BV(WGM21); \
|
||||
TCCR2B = _BV(CS20); \
|
||||
OCR2A = TIMER_COUNT_TOP; \
|
||||
TCNT2 = 0; \
|
||||
})
|
||||
#else
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR2A = _BV(WGM21); \
|
||||
TCCR2B = _BV(CS21); \
|
||||
OCR2A = TIMER_COUNT_TOP / 8; \
|
||||
TCNT2 = 0; \
|
||||
})
|
||||
#endif
|
||||
#if defined(CORE_OC2B_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 14 /* Sanguino */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer1 (16 bits)
|
||||
#elif defined(IR_USE_TIMER1)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
||||
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK = 0)
|
||||
#else
|
||||
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||
#endif
|
||||
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR1A = _BV(WGM11); \
|
||||
TCCR1B = _BV(WGM13) | _BV(CS10); \
|
||||
ICR1 = pwmval; \
|
||||
OCR1A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR1A = 0; \
|
||||
TCCR1B = _BV(WGM12) | _BV(CS10); \
|
||||
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT1 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC1A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 11 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 13 /* Sanguino */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer3 (16 bits)
|
||||
#elif defined(IR_USE_TIMER3)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
|
||||
#define TIMER_INTR_NAME TIMER3_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR3A = _BV(WGM31); \
|
||||
TCCR3B = _BV(WGM33) | _BV(CS30); \
|
||||
ICR3 = pwmval; \
|
||||
OCR3A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR3A = 0; \
|
||||
TCCR3B = _BV(WGM32) | _BV(CS30); \
|
||||
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT3 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC3A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 5 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC3A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (10 bits, high speed option)
|
||||
#elif defined(IR_USE_TIMER4_HS)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_OVF_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = (1<<PWM4A); \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = (1<<WGM40); \
|
||||
TCCR4E = 0; \
|
||||
TC4H = pwmval >> 8; \
|
||||
OCR4C = pwmval; \
|
||||
TC4H = (pwmval / 3) >> 8; \
|
||||
OCR4A = (pwmval / 3) & 255; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = 0; \
|
||||
TCCR4E = 0; \
|
||||
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
|
||||
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
|
||||
TC4H = 0; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 13 /* Leonardo */
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (16 bits)
|
||||
#elif defined(IR_USE_TIMER4)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = _BV(WGM41); \
|
||||
TCCR4B = _BV(WGM43) | _BV(CS40); \
|
||||
ICR4 = pwmval; \
|
||||
OCR4A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(WGM42) | _BV(CS40); \
|
||||
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 6 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer5 (16 bits)
|
||||
#elif defined(IR_USE_TIMER5)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
|
||||
#define TIMER_INTR_NAME TIMER5_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR5A = _BV(WGM51); \
|
||||
TCCR5B = _BV(WGM53) | _BV(CS50); \
|
||||
ICR5 = pwmval; \
|
||||
OCR5A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR5A = 0; \
|
||||
TCCR5B = _BV(WGM52) | _BV(CS50); \
|
||||
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT5 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC5A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC5A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 46 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC5A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for special carrier modulator timer
|
||||
#elif defined(IR_USE_TIMER_CMT)
|
||||
#define TIMER_RESET ({ \
|
||||
uint8_t tmp = CMT_MSC; \
|
||||
CMT_CMD2 = 30; \
|
||||
})
|
||||
#define TIMER_ENABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_DSE|PORT_PCR_SRE
|
||||
#define TIMER_DISABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE
|
||||
#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
|
||||
#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
|
||||
#define TIMER_INTR_NAME cmt_isr
|
||||
#ifdef ISR
|
||||
#undef ISR
|
||||
#endif
|
||||
#define ISR(f) void f(void)
|
||||
#if F_BUS == 48000000
|
||||
#define CMT_PPS_VAL 5
|
||||
#else
|
||||
#define CMT_PPS_VAL 2
|
||||
#endif
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
||||
SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
|
||||
CMT_PPS = CMT_PPS_VAL; \
|
||||
CMT_CGH1 = 2667 / val; \
|
||||
CMT_CGL1 = 5333 / val; \
|
||||
CMT_CMD1 = 0; \
|
||||
CMT_CMD2 = 30; \
|
||||
CMT_CMD3 = 0; \
|
||||
CMT_CMD4 = 0; \
|
||||
CMT_OC = 0x60; \
|
||||
CMT_MSC = 0x01; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
||||
CMT_PPS = CMT_PPS_VAL; \
|
||||
CMT_CGH1 = 1; \
|
||||
CMT_CGL1 = 1; \
|
||||
CMT_CMD1 = 0; \
|
||||
CMT_CMD2 = 30; \
|
||||
CMT_CMD3 = 0; \
|
||||
CMT_CMD4 = 19; \
|
||||
CMT_OC = 0; \
|
||||
CMT_MSC = 0x03; \
|
||||
})
|
||||
#define TIMER_PWM_PIN 5
|
||||
|
||||
|
||||
#else // unknown timer
|
||||
#error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for blinking the LED
|
||||
#if defined(CORE_LED0_PIN)
|
||||
#define BLINKLED CORE_LED0_PIN
|
||||
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
|
||||
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B10000000)
|
||||
#define BLINKLED_OFF() (PORTB &= B01111111)
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define BLINKLED 0
|
||||
#define BLINKLED_ON() (PORTD |= B00000001)
|
||||
#define BLINKLED_OFF() (PORTD &= B11111110)
|
||||
#else
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B00100000)
|
||||
#define BLINKLED_OFF() (PORTB &= B11011111)
|
||||
#endif
|
||||
|
||||
#endif
|
458
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/LICENSE.txt
Executable file
458
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/LICENSE.txt
Executable file
@ -0,0 +1,458 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* IRrecord: record and play back IR signals as a minimal
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* An IR LED must be connected to the output PWM pin 3.
|
||||
* A button must be connected to the input BUTTON_PIN; this is the
|
||||
* send button.
|
||||
* A visible LED can be connected to STATUS_PIN to provide status.
|
||||
*
|
||||
* The logic is:
|
||||
* If the button is pressed, send the IR code.
|
||||
* If an IR code is received, record it.
|
||||
*
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include </Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.h>
|
||||
#include </Users/Imogen/Documents/Arduino/libraries/IRremote/IRremote.cpp>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int BUTTON_PIN = 12;
|
||||
int STATUS_PIN = 13;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
IRsend irsend;
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
pinMode(STATUS_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
// Storage for the recorded code
|
||||
int codeType = -1; // The type of code
|
||||
unsigned long codeValue; // The code value if not raw
|
||||
unsigned int rawCodes[RAWBUF]; // The durations if raw
|
||||
int codeLen; // The length of the code
|
||||
int toggle = 0; // The RC5/6 toggle state
|
||||
|
||||
// Stores the code for later playback
|
||||
// Most of this code is just logging
|
||||
void storeCode(decode_results *results) {
|
||||
codeType = results->decode_type;
|
||||
int count = results->rawlen;
|
||||
if (codeType == UNKNOWN) {
|
||||
Serial.println("Received unknown code, saving as raw");
|
||||
codeLen = results->rawlen - 1;
|
||||
// To store raw codes:
|
||||
// Drop first value (gap)
|
||||
// Convert from ticks to microseconds
|
||||
// Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
|
||||
for (int i = 1; i <= codeLen; i++) {
|
||||
if (i % 2) {
|
||||
// Mark
|
||||
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
|
||||
Serial.print(" m");
|
||||
}
|
||||
else {
|
||||
// Space
|
||||
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
|
||||
Serial.print(" s");
|
||||
}
|
||||
Serial.print(rawCodes[i - 1], DEC);
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
else {
|
||||
if (codeType == NEC) {
|
||||
Serial.print("Received NEC: ");
|
||||
if (results->value == REPEAT) {
|
||||
// Don't record a NEC repeat value as that's useless.
|
||||
Serial.println("repeat; ignoring.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (codeType == SONY) {
|
||||
Serial.print("Received SONY: ");
|
||||
}
|
||||
else if (codeType == RC5) {
|
||||
Serial.print("Received RC5: ");
|
||||
}
|
||||
else if (codeType == RC6) {
|
||||
Serial.print("Received RC6: ");
|
||||
}
|
||||
else {
|
||||
Serial.print("Unexpected codeType ");
|
||||
Serial.print(codeType, DEC);
|
||||
Serial.println("");
|
||||
}
|
||||
Serial.println(results->value, HEX);
|
||||
codeValue = results->value;
|
||||
codeLen = results->bits;
|
||||
}
|
||||
}
|
||||
|
||||
void sendCode(int repeat) {
|
||||
if (codeType == NEC) {
|
||||
if (repeat) {
|
||||
irsend.sendNEC(REPEAT, codeLen);
|
||||
Serial.println("Sent NEC repeat");
|
||||
}
|
||||
else {
|
||||
irsend.sendNEC(codeValue, codeLen);
|
||||
Serial.print("Sent NEC ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
}
|
||||
else if (codeType == SONY) {
|
||||
irsend.sendSony(codeValue, codeLen);
|
||||
Serial.print("Sent Sony ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
else if (codeType == RC5 || codeType == RC6) {
|
||||
if (!repeat) {
|
||||
// Flip the toggle bit for a new button press
|
||||
toggle = 1 - toggle;
|
||||
}
|
||||
// Put the toggle bit into the code to send
|
||||
codeValue = codeValue & ~(1 << (codeLen - 1));
|
||||
codeValue = codeValue | (toggle << (codeLen - 1));
|
||||
if (codeType == RC5) {
|
||||
Serial.print("Sent RC5 ");
|
||||
Serial.println(codeValue, HEX);
|
||||
irsend.sendRC5(codeValue, codeLen);
|
||||
}
|
||||
else {
|
||||
irsend.sendRC6(codeValue, codeLen);
|
||||
Serial.print("Sent RC6 ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
}
|
||||
else if (codeType == UNKNOWN /* i.e. raw */) {
|
||||
// Assume 38 KHz
|
||||
irsend.sendRaw(rawCodes, codeLen, 38);
|
||||
Serial.println("Sent raw");
|
||||
}
|
||||
}
|
||||
|
||||
int lastButtonState;
|
||||
|
||||
void loop() {
|
||||
// If button pressed, send the code.
|
||||
int buttonState = digitalRead(BUTTON_PIN);
|
||||
if (lastButtonState == HIGH && buttonState == LOW) {
|
||||
Serial.println("Released");
|
||||
irrecv.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
|
||||
if (buttonState) {
|
||||
Serial.println("Pressed, sending");
|
||||
digitalWrite(STATUS_PIN, HIGH);
|
||||
sendCode(lastButtonState == buttonState);
|
||||
digitalWrite(STATUS_PIN, LOW);
|
||||
delay(50); // Wait a bit between retransmissions
|
||||
}
|
||||
else if (irrecv.decode(&results)) {
|
||||
digitalWrite(STATUS_PIN, HIGH);
|
||||
storeCode(&results);
|
||||
irrecv.resume(); // resume receiver
|
||||
digitalWrite(STATUS_PIN, LOW);
|
||||
}
|
||||
lastButtonState = buttonState;
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com
|
||||
* Edited by Mitra to add new controller SANYO
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
* LG added by Darryl Smith (based on the JVC protocol)
|
||||
*/
|
||||
|
||||
#ifndef IRremote_h
|
||||
#define IRremote_h
|
||||
|
||||
// The following are compile-time library options.
|
||||
// If you change them, recompile the library.
|
||||
// If DEBUG is defined, a lot of debugging output will be printed during decoding.
|
||||
// TEST must be defined for the IRtest unittests to work. It will make some
|
||||
// methods virtual, which will be slightly slower, which is why it is optional.
|
||||
// #define DEBUG
|
||||
// #define TEST
|
||||
|
||||
// Results returned from the decoder
|
||||
class decode_results {
|
||||
public:
|
||||
int decode_type; // NEC, SONY, RC5, UNKNOWN
|
||||
union { // This is used for decoding Panasonic and Sharp data
|
||||
unsigned int panasonicAddress;
|
||||
unsigned int sharpAddress;
|
||||
};
|
||||
unsigned long value; // Decoded value
|
||||
int bits; // Number of bits in decoded value
|
||||
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||
int rawlen; // Number of records in rawbuf.
|
||||
};
|
||||
|
||||
// Values for decode_type
|
||||
#define NEC 1
|
||||
#define SONY 2
|
||||
#define RC5 3
|
||||
#define RC6 4
|
||||
#define DISH 5
|
||||
#define SHARP 6
|
||||
#define PANASONIC 7
|
||||
#define JVC 8
|
||||
#define SANYO 9
|
||||
#define MITSUBISHI 10
|
||||
#define SAMSUNG 11
|
||||
#define LG 12
|
||||
#define UNKNOWN -1
|
||||
|
||||
// Decoded value for NEC when a repeat code is received
|
||||
#define REPEAT 0xffffffff
|
||||
|
||||
// main class for receiving IR
|
||||
class IRrecv
|
||||
{
|
||||
public:
|
||||
IRrecv(int recvpin);
|
||||
void blink13(int blinkflag);
|
||||
int decode(decode_results *results);
|
||||
void enableIRIn();
|
||||
void resume();
|
||||
private:
|
||||
// These are called by decode
|
||||
int getRClevel(decode_results *results, int *offset, int *used, int t1);
|
||||
long decodeNEC(decode_results *results);
|
||||
long decodeSony(decode_results *results);
|
||||
long decodeSanyo(decode_results *results);
|
||||
long decodeMitsubishi(decode_results *results);
|
||||
long decodeRC5(decode_results *results);
|
||||
long decodeRC6(decode_results *results);
|
||||
long decodePanasonic(decode_results *results);
|
||||
long decodeLG(decode_results *results);
|
||||
long decodeJVC(decode_results *results);
|
||||
long decodeSAMSUNG(decode_results *results);
|
||||
long decodeHash(decode_results *results);
|
||||
int compare(unsigned int oldval, unsigned int newval);
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
// Only used for testing; can remove virtual for shorter code
|
||||
#ifdef TEST
|
||||
#define VIRTUAL virtual
|
||||
#else
|
||||
#define VIRTUAL
|
||||
#endif
|
||||
|
||||
class IRsend
|
||||
{
|
||||
public:
|
||||
IRsend() {}
|
||||
void sendNEC(unsigned long data, int nbits);
|
||||
void sendSony(unsigned long data, int nbits);
|
||||
// Neither Sanyo nor Mitsubishi send is implemented yet
|
||||
// void sendSanyo(unsigned long data, int nbits);
|
||||
// void sendMitsubishi(unsigned long data, int nbits);
|
||||
void sendRaw(unsigned int buf[], int len, int hz);
|
||||
void sendRC5(unsigned long data, int nbits);
|
||||
void sendRC6(unsigned long data, int nbits);
|
||||
void sendDISH(unsigned long data, int nbits);
|
||||
void sendSharp(unsigned int address, unsigned int command);
|
||||
void sendSharpRaw(unsigned long data, int nbits);
|
||||
void sendPanasonic(unsigned int address, unsigned long data);
|
||||
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
|
||||
// private:
|
||||
void sendSAMSUNG(unsigned long data, int nbits);
|
||||
void enableIROut(int khz);
|
||||
VIRTUAL void mark(int usec);
|
||||
VIRTUAL void space(int usec);
|
||||
}
|
||||
;
|
||||
|
||||
// Some useful constants
|
||||
|
||||
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||
#define RAWBUF 100 // Length of raw duration buffer
|
||||
|
||||
// Marks tend to be 100us too long, and spaces 100us too short
|
||||
// when received due to sensor lag.
|
||||
#define MARK_EXCESS 100
|
||||
|
||||
#endif
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
delay(100);
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* IRremote: IRrecvDump - dump details of IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
* LG added by Darryl Smith (based on the JVC protocol)
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.print("Unknown encoding: ");
|
||||
}
|
||||
else if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
else if (results->decode_type == PANASONIC) {
|
||||
Serial.print("Decoded PANASONIC - Address: ");
|
||||
Serial.print(results->panasonicAddress,HEX);
|
||||
Serial.print(" Value: ");
|
||||
}
|
||||
else if (results->decode_type == LG) {
|
||||
Serial.print("Decoded LG: ");
|
||||
}
|
||||
else if (results->decode_type == JVC) {
|
||||
Serial.print("Decoded JVC: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
dump(&results);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int RELAY_PIN = 4;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
decode_results results;
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
int on = 0;
|
||||
unsigned long last = millis();
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
// If it's been at least 1/4 second since the last
|
||||
// IR received, toggle the relay
|
||||
if (millis() - last > 250) {
|
||||
on = !on;
|
||||
digitalWrite(RELAY_PIN, on ? HIGH : LOW);
|
||||
digitalWrite(13, on ? HIGH : LOW);
|
||||
dump(&results);
|
||||
}
|
||||
last = millis();
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
irsend.sendSony(0xa90, 12); // Sony TV power code
|
||||
delay(40);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* IRremote: IRtest unittest
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*
|
||||
* Note: to run these tests, edit IRremote/IRremote.h to add "#define TEST"
|
||||
* You must then recompile the library by removing IRremote.o and restarting
|
||||
* the arduino IDE.
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
#include <IRremoteInt.h>
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
IRrecv irrecv(0);
|
||||
decode_results results;
|
||||
|
||||
class IRsendDummy :
|
||||
public IRsend
|
||||
{
|
||||
public:
|
||||
// For testing, just log the marks/spaces
|
||||
#define SENDLOG_LEN 128
|
||||
int sendlog[SENDLOG_LEN];
|
||||
int sendlogcnt;
|
||||
IRsendDummy() :
|
||||
IRsend() {
|
||||
}
|
||||
void reset() {
|
||||
sendlogcnt = 0;
|
||||
}
|
||||
void mark(int time) {
|
||||
sendlog[sendlogcnt] = time;
|
||||
if (sendlogcnt < SENDLOG_LEN) sendlogcnt++;
|
||||
}
|
||||
void space(int time) {
|
||||
sendlog[sendlogcnt] = -time;
|
||||
if (sendlogcnt < SENDLOG_LEN) sendlogcnt++;
|
||||
}
|
||||
// Copies the dummy buf into the interrupt buf
|
||||
void useDummyBuf() {
|
||||
int last = SPACE;
|
||||
irparams.rcvstate = STATE_STOP;
|
||||
irparams.rawlen = 1; // Skip the gap
|
||||
for (int i = 0 ; i < sendlogcnt; i++) {
|
||||
if (sendlog[i] < 0) {
|
||||
if (last == MARK) {
|
||||
// New space
|
||||
irparams.rawbuf[irparams.rawlen++] = (-sendlog[i] - MARK_EXCESS) / USECPERTICK;
|
||||
last = SPACE;
|
||||
}
|
||||
else {
|
||||
// More space
|
||||
irparams.rawbuf[irparams.rawlen - 1] += -sendlog[i] / USECPERTICK;
|
||||
}
|
||||
}
|
||||
else if (sendlog[i] > 0) {
|
||||
if (last == SPACE) {
|
||||
// New mark
|
||||
irparams.rawbuf[irparams.rawlen++] = (sendlog[i] + MARK_EXCESS) / USECPERTICK;
|
||||
last = MARK;
|
||||
}
|
||||
else {
|
||||
// More mark
|
||||
irparams.rawbuf[irparams.rawlen - 1] += sendlog[i] / USECPERTICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (irparams.rawlen % 2) {
|
||||
irparams.rawlen--; // Remove trailing space
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IRsendDummy irsenddummy;
|
||||
|
||||
void verify(unsigned long val, int bits, int type) {
|
||||
irsenddummy.useDummyBuf();
|
||||
irrecv.decode(&results);
|
||||
Serial.print("Testing ");
|
||||
Serial.print(val, HEX);
|
||||
if (results.value == val && results.bits == bits && results.decode_type == type) {
|
||||
Serial.println(": OK");
|
||||
}
|
||||
else {
|
||||
Serial.println(": Error");
|
||||
dump(&results);
|
||||
}
|
||||
}
|
||||
|
||||
void testNEC(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendNEC(val, bits);
|
||||
verify(val, bits, NEC);
|
||||
}
|
||||
void testSony(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendSony(val, bits);
|
||||
verify(val, bits, SONY);
|
||||
}
|
||||
void testRC5(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendRC5(val, bits);
|
||||
verify(val, bits, RC5);
|
||||
}
|
||||
void testRC6(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendRC6(val, bits);
|
||||
verify(val, bits, RC6);
|
||||
}
|
||||
|
||||
void test() {
|
||||
Serial.println("NEC tests");
|
||||
testNEC(0x00000000, 32);
|
||||
testNEC(0xffffffff, 32);
|
||||
testNEC(0xaaaaaaaa, 32);
|
||||
testNEC(0x55555555, 32);
|
||||
testNEC(0x12345678, 32);
|
||||
Serial.println("Sony tests");
|
||||
testSony(0xfff, 12);
|
||||
testSony(0x000, 12);
|
||||
testSony(0xaaa, 12);
|
||||
testSony(0x555, 12);
|
||||
testSony(0x123, 12);
|
||||
Serial.println("RC5 tests");
|
||||
testRC5(0xfff, 12);
|
||||
testRC5(0x000, 12);
|
||||
testRC5(0xaaa, 12);
|
||||
testRC5(0x555, 12);
|
||||
testRC5(0x123, 12);
|
||||
Serial.println("RC6 tests");
|
||||
testRC6(0xfffff, 20);
|
||||
testRC6(0x00000, 20);
|
||||
testRC6(0xaaaaa, 20);
|
||||
testRC6(0x55555, 20);
|
||||
testRC6(0x12345, 20);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
test();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Test send/receive functions of IRremote, using a pair of Arduinos.
|
||||
*
|
||||
* Arduino #1 should have an IR LED connected to the send pin (3).
|
||||
* Arduino #2 should have an IR detector/demodulator connected to the
|
||||
* receive pin (11) and a visible LED connected to pin 3.
|
||||
*
|
||||
* The cycle:
|
||||
* Arduino #1 will wait 2 seconds, then run through the tests.
|
||||
* It repeats this forever.
|
||||
* Arduino #2 will wait for at least one second of no signal
|
||||
* (to synchronize with #1). It will then wait for the same test
|
||||
* signals. It will log all the status to the serial port. It will
|
||||
* also indicate status through the LED, which will flash each time a test
|
||||
* is completed. If there is an error, it will light up for 5 seconds.
|
||||
*
|
||||
* The test passes if the LED flashes 19 times, pauses, and then repeats.
|
||||
* The test fails if the LED lights for 5 seconds.
|
||||
*
|
||||
* The test software automatically decides which board is the sender and which is
|
||||
* the receiver by looking for an input on the send pin, which will indicate
|
||||
* the sender. You should hook the serial port to the receiver for debugging.
|
||||
*
|
||||
* Copyright 2010 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int LED_PIN = 3;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
IRsend irsend;
|
||||
|
||||
decode_results results;
|
||||
|
||||
#define RECEIVER 1
|
||||
#define SENDER 2
|
||||
#define ERROR 3
|
||||
|
||||
int mode;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
// Check RECV_PIN to decide if we're RECEIVER or SENDER
|
||||
if (digitalRead(RECV_PIN) == HIGH) {
|
||||
mode = RECEIVER;
|
||||
irrecv.enableIRIn();
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
Serial.println("Receiver mode");
|
||||
}
|
||||
else {
|
||||
mode = SENDER;
|
||||
Serial.println("Sender mode");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the gap between tests, to synchronize with
|
||||
// the sender.
|
||||
// Specifically, wait for a signal followed by a gap of at last gap ms.
|
||||
void waitForGap(int gap) {
|
||||
Serial.println("Waiting for gap");
|
||||
while (1) {
|
||||
while (digitalRead(RECV_PIN) == LOW) {
|
||||
}
|
||||
unsigned long time = millis();
|
||||
while (digitalRead(RECV_PIN) == HIGH) {
|
||||
if (millis() - time > gap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
// Test send or receive.
|
||||
// If mode is SENDER, send a code of the specified type, value, and bits
|
||||
// If mode is RECEIVER, receive a code and verify that it is of the
|
||||
// specified type, value, and bits. For success, the LED is flashed;
|
||||
// for failure, the mode is set to ERROR.
|
||||
// The motivation behind this method is that the sender and the receiver
|
||||
// can do the same test calls, and the mode variable indicates whether
|
||||
// to send or receive.
|
||||
void test(char *label, int type, unsigned long value, int bits) {
|
||||
if (mode == SENDER) {
|
||||
Serial.println(label);
|
||||
if (type == NEC) {
|
||||
irsend.sendNEC(value, bits);
|
||||
}
|
||||
else if (type == SONY) {
|
||||
irsend.sendSony(value, bits);
|
||||
}
|
||||
else if (type == RC5) {
|
||||
irsend.sendRC5(value, bits);
|
||||
}
|
||||
else if (type == RC6) {
|
||||
irsend.sendRC6(value, bits);
|
||||
}
|
||||
else {
|
||||
Serial.print(label);
|
||||
Serial.println("Bad type!");
|
||||
}
|
||||
delay(200);
|
||||
}
|
||||
else if (mode == RECEIVER) {
|
||||
irrecv.resume(); // Receive the next value
|
||||
unsigned long max_time = millis() + 30000;
|
||||
Serial.print(label);
|
||||
|
||||
// Wait for decode or timeout
|
||||
while (!irrecv.decode(&results)) {
|
||||
if (millis() > max_time) {
|
||||
Serial.println("Timeout receiving data");
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (type == results.decode_type && value == results.value && bits == results.bits) {
|
||||
Serial.println (": OK");
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
else {
|
||||
Serial.println(": BAD");
|
||||
dump(&results);
|
||||
mode = ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test raw send or receive. This is similar to the test method,
|
||||
// except it send/receives raw data.
|
||||
void testRaw(char *label, unsigned int *rawbuf, int rawlen) {
|
||||
if (mode == SENDER) {
|
||||
Serial.println(label);
|
||||
irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */);
|
||||
delay(200);
|
||||
}
|
||||
else if (mode == RECEIVER ) {
|
||||
irrecv.resume(); // Receive the next value
|
||||
unsigned long max_time = millis() + 30000;
|
||||
Serial.print(label);
|
||||
|
||||
// Wait for decode or timeout
|
||||
while (!irrecv.decode(&results)) {
|
||||
if (millis() > max_time) {
|
||||
Serial.println("Timeout receiving data");
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Received length has extra first element for gap
|
||||
if (rawlen != results.rawlen - 1) {
|
||||
Serial.print("Bad raw length ");
|
||||
Serial.println(results.rawlen, DEC);
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < rawlen; i++) {
|
||||
long got = results.rawbuf[i+1] * USECPERTICK;
|
||||
// Adjust for extra duration of marks
|
||||
if (i % 2 == 0) {
|
||||
got -= MARK_EXCESS;
|
||||
}
|
||||
else {
|
||||
got += MARK_EXCESS;
|
||||
}
|
||||
// See if close enough, within 25%
|
||||
if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) {
|
||||
Serial.println(": BAD");
|
||||
dump(&results);
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
Serial.println (": OK");
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// This is the raw data corresponding to NEC 0x12345678
|
||||
unsigned int sendbuf[] = { /* NEC format */
|
||||
9000, 4500,
|
||||
560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */
|
||||
560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */
|
||||
560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */
|
||||
560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */
|
||||
560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */
|
||||
560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */
|
||||
560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */
|
||||
560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */
|
||||
560};
|
||||
|
||||
void loop() {
|
||||
if (mode == SENDER) {
|
||||
delay(2000); // Delay for more than gap to give receiver a better chance to sync.
|
||||
}
|
||||
else if (mode == RECEIVER) {
|
||||
waitForGap(1000);
|
||||
}
|
||||
else if (mode == ERROR) {
|
||||
// Light up for 5 seconds for error
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(5000);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
mode = RECEIVER; // Try again
|
||||
return;
|
||||
}
|
||||
|
||||
// The test suite.
|
||||
test("SONY1", SONY, 0x123, 12);
|
||||
test("SONY2", SONY, 0x000, 12);
|
||||
test("SONY3", SONY, 0xfff, 12);
|
||||
test("SONY4", SONY, 0x12345, 20);
|
||||
test("SONY5", SONY, 0x00000, 20);
|
||||
test("SONY6", SONY, 0xfffff, 20);
|
||||
test("NEC1", NEC, 0x12345678, 32);
|
||||
test("NEC2", NEC, 0x00000000, 32);
|
||||
test("NEC3", NEC, 0xffffffff, 32);
|
||||
test("NEC4", NEC, REPEAT, 32);
|
||||
test("RC51", RC5, 0x12345678, 32);
|
||||
test("RC52", RC5, 0x0, 32);
|
||||
test("RC53", RC5, 0xffffffff, 32);
|
||||
test("RC61", RC6, 0x12345678, 32);
|
||||
test("RC62", RC6, 0x0, 32);
|
||||
test("RC63", RC6, 0xffffffff, 32);
|
||||
|
||||
// Tests of raw sending and receiving.
|
||||
// First test sending raw and receiving raw.
|
||||
// Then test sending raw and receiving decoded NEC
|
||||
// Then test sending NEC and receiving raw
|
||||
testRaw("RAW1", sendbuf, 67);
|
||||
if (mode == SENDER) {
|
||||
testRaw("RAW2", sendbuf, 67);
|
||||
test("RAW3", NEC, 0x12345678, 32);
|
||||
}
|
||||
else {
|
||||
test("RAW2", NEC, 0x12345678, 32);
|
||||
testRaw("RAW3", sendbuf, 67);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
#include <IRremote.h>
|
||||
|
||||
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
|
||||
#define PanasonicPower 0x100BCBD // Panasonic Power button
|
||||
|
||||
#define JVCPower 0xC5E8
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void loop() {
|
||||
irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off
|
||||
|
||||
irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat
|
||||
delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information
|
||||
irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat
|
||||
delayMicroseconds(50);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For IRremote
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
decode_results KEYWORD1
|
||||
IRrecv KEYWORD1
|
||||
IRsend KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
blink13 KEYWORD2
|
||||
decode KEYWORD2
|
||||
enableIRIn KEYWORD2
|
||||
resume KEYWORD2
|
||||
enableIROut KEYWORD2
|
||||
sendNEC KEYWORD2
|
||||
sendSony KEYWORD2
|
||||
sendSanyo KEYWORD2
|
||||
sendMitsubishi KEYWORD2
|
||||
sendRaw KEYWORD2
|
||||
sendRC5 KEYWORD2
|
||||
sendRC6 KEYWORD2
|
||||
sendDISH KEYWORD2
|
||||
sendSharp KEYWORD2
|
||||
sendSharpRaw KEYWORD2
|
||||
sendPanasonic KEYWORD2
|
||||
sendJVC KEYWORD2
|
||||
|
||||
#
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
NEC LITERAL1
|
||||
SONY LITERAL1
|
||||
SANYO LITERAL1
|
||||
MITSUBISHI LITERAL1
|
||||
RC5 LITERAL1
|
||||
RC6 LITERAL1
|
||||
DISH LITERAL1
|
||||
SHARP LITERAL1
|
||||
PANASONIC LITERAL1
|
||||
JVC LITERAL1
|
||||
UNKNOWN LITERAL1
|
||||
REPEAT LITERAL1
|
14
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/readme
Executable file
14
projects/elegoo-kit-lessons/Lesson 13 IR Receiver Module/IRremote/readme
Executable file
@ -0,0 +1,14 @@
|
||||
This is the IRremote library for the Arduino.
|
||||
|
||||
To download from github (http://github.com/shirriff/Arduino-IRremote), click on the "Downloads" link in the upper right, click "Download as zip", and get a zip file. Unzip it and rename the directory shirriff-Arduino-IRremote-nnn to IRremote
|
||||
|
||||
To install, move the downloaded IRremote directory to:
|
||||
arduino-1.x/libraries/IRremote
|
||||
where arduino-1.x is your Arduino installation directory
|
||||
|
||||
After installation you should have files such as:
|
||||
arduino-1.x/libraries/IRremote/IRremote.cpp
|
||||
|
||||
For details on the library see the Wiki on github or the blog post http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
|
||||
Copyright 2009-2012 Ken Shirriff
|
BIN
projects/elegoo-kit-lessons/Lesson 14 LCD Display/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 14 LCD Display/.DS_Store
vendored
Normal file
Binary file not shown.
63
projects/elegoo-kit-lessons/Lesson 14 LCD Display/HelloWorld/HelloWorld.ino
Executable file
63
projects/elegoo-kit-lessons/Lesson 14 LCD Display/HelloWorld/HelloWorld.ino
Executable file
@ -0,0 +1,63 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
/*
|
||||
LiquidCrystal Library - Hello World
|
||||
|
||||
Demonstrates the use a 16x2 LCD display. The LiquidCrystal
|
||||
library works with all LCD displays that are compatible with the
|
||||
Hitachi HD44780 driver. There are many of them out there, and you
|
||||
can usually tell them by the 16-pin interface.
|
||||
|
||||
This sketch prints "Hello World!" to the LCD
|
||||
and shows the time.
|
||||
|
||||
The circuit:
|
||||
* LCD RS pin to digital pin 7
|
||||
* LCD Enable pin to digital pin 8
|
||||
* LCD D4 pin to digital pin 9
|
||||
* LCD D5 pin to digital pin 10
|
||||
* LCD D6 pin to digital pin 11
|
||||
* LCD D7 pin to digital pin 12
|
||||
* LCD R/W pin to ground
|
||||
* LCD VSS pin to ground
|
||||
* LCD VCC pin to 5V
|
||||
* 10K resistor:
|
||||
* ends to +5V and ground
|
||||
* wiper to LCD VO pin (pin 3)
|
||||
|
||||
Library originally added 18 Apr 2008
|
||||
by David A. Mellis
|
||||
library modified 5 Jul 2009
|
||||
by Limor Fried (http://www.ladyada.net)
|
||||
example added 9 Jul 2009
|
||||
by Tom Igoe
|
||||
modified 22 Nov 2010
|
||||
by Tom Igoe
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
http://www.arduino.cc/en/Tutorial/LiquidCrystal
|
||||
*/
|
||||
|
||||
// include the library code:
|
||||
#include <LiquidCrystal.h>
|
||||
|
||||
// initialize the library with the numbers of the interface pins
|
||||
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
|
||||
|
||||
void setup() {
|
||||
// set up the LCD's number of columns and rows:
|
||||
lcd.begin(16, 2);
|
||||
// Print a message to the LCD.
|
||||
lcd.print("Hello, World!");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// set the cursor to column 0, line 1
|
||||
// (note: line 1 is the second row, since counting begins with 0):
|
||||
lcd.setCursor(0, 1);
|
||||
// print the number of seconds since reset:
|
||||
lcd.print(millis() / 1000);
|
||||
}
|
||||
|
BIN
projects/elegoo-kit-lessons/Lesson 14 LCD Display/LiquidCrystal.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 14 LCD Display/LiquidCrystal.zip
Executable file
Binary file not shown.
BIN
projects/elegoo-kit-lessons/Lesson 15 Thermometer/LiquidCrystal.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 15 Thermometer/LiquidCrystal.zip
Executable file
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
#include <LiquidCrystal.h>
|
||||
int tempPin = 0;
|
||||
// BS E D4 D5 D6 D7
|
||||
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
|
||||
void setup()
|
||||
{
|
||||
lcd.begin(16, 2);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
int tempReading = analogRead(tempPin);
|
||||
// This is OK
|
||||
double tempK = log(10000.0 * ((1024.0 / tempReading - 1)));
|
||||
tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK ); // Temp Kelvin
|
||||
float tempC = tempK - 273.15; // Convert Kelvin to Celcius
|
||||
float tempF = (tempC * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
|
||||
/* replaced
|
||||
float tempVolts = tempReading * 5.0 / 1024.0;
|
||||
float tempC = (tempVolts - 0.5) * 10.0;
|
||||
float tempF = tempC * 9.0 / 5.0 + 32.0;
|
||||
*/
|
||||
// Display Temperature in C
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Temp C ");
|
||||
// Display Temperature in F
|
||||
//lcd.print("Temp F ");
|
||||
lcd.setCursor(6, 0);
|
||||
// Display Temperature in C
|
||||
lcd.print(tempC);
|
||||
// Display Temperature in F
|
||||
//lcd.print(tempF);
|
||||
delay(500);
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
int tDelay = 100;
|
||||
int latchPin = 11; // (11) ST_CP [RCK] on 74HC595
|
||||
int clockPin = 9; // (9) SH_CP [SCK] on 74HC595
|
||||
int dataPin = 12; // (12) DS [S1] on 74HC595
|
||||
|
||||
byte leds = 0;
|
||||
|
||||
void updateShiftRegister()
|
||||
{
|
||||
digitalWrite(latchPin, LOW);
|
||||
shiftOut(dataPin, clockPin, LSBFIRST, leds);
|
||||
digitalWrite(latchPin, HIGH);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(latchPin, OUTPUT);
|
||||
pinMode(dataPin, OUTPUT);
|
||||
pinMode(clockPin, OUTPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
leds = 0;
|
||||
updateShiftRegister();
|
||||
delay(tDelay);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bitSet(leds, i);
|
||||
updateShiftRegister();
|
||||
delay(tDelay);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
int latchPin = 11;
|
||||
int clockPin = 9;
|
||||
int dataPin = 12;
|
||||
|
||||
byte leds = 0;
|
||||
void updateShiftRegister()
|
||||
{
|
||||
digitalWrite(latchPin, LOW);
|
||||
shiftOut(dataPin, clockPin, LSBFIRST, leds);
|
||||
digitalWrite(latchPin, HIGH);
|
||||
}
|
||||
void setup()
|
||||
{
|
||||
pinMode(latchPin, OUTPUT);
|
||||
pinMode(dataPin, OUTPUT);
|
||||
pinMode(clockPin, OUTPUT);
|
||||
updateShiftRegister();
|
||||
Serial.begin(9600);
|
||||
while (! Serial); // Wait untilSerial is ready - Leonardo
|
||||
Serial.println("Enter LED Number 0 to 7 or 'x' to clear");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (Serial.available())
|
||||
{
|
||||
char ch = Serial.read();
|
||||
if (ch >= '0' && ch <= '7')
|
||||
{
|
||||
int led = ch - '0';
|
||||
bitSet(leds, led);
|
||||
updateShiftRegister();
|
||||
Serial.print("Turned on LED ");
|
||||
Serial.println(led);
|
||||
}
|
||||
if (ch == 'x')
|
||||
{
|
||||
leds = 0;
|
||||
updateShiftRegister();
|
||||
Serial.println("Cleared");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
36
projects/elegoo-kit-lessons/Lesson 18 Photocell/Photocell/Photocell.ino
Executable file
36
projects/elegoo-kit-lessons/Lesson 18 Photocell/Photocell/Photocell.ino
Executable file
@ -0,0 +1,36 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.9
|
||||
|
||||
int lightPin = 0;
|
||||
int latchPin = 11;
|
||||
int clockPin = 9;
|
||||
int dataPin = 12;
|
||||
|
||||
int leds = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(latchPin, OUTPUT);
|
||||
pinMode(dataPin, OUTPUT);
|
||||
pinMode(clockPin, OUTPUT);
|
||||
}
|
||||
void updateShiftRegister()
|
||||
{
|
||||
digitalWrite(latchPin, LOW);
|
||||
shiftOut(dataPin, clockPin, LSBFIRST, leds);
|
||||
digitalWrite(latchPin, HIGH);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
int reading = analogRead(lightPin);
|
||||
int numLEDSLit = reading / 57; //1023 / 9 / 2
|
||||
if (numLEDSLit > 8) numLEDSLit = 8;
|
||||
leds = 0; // no LEDs lit to start
|
||||
for (int i = 0; i < numLEDSLit; i++)
|
||||
{
|
||||
leds = leds + (1 << i); // sets the i'th bit
|
||||
}
|
||||
updateShiftRegister();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.12
|
||||
|
||||
// define the LED digit patterns, from 0 - 9
|
||||
// 1 = LED on, 0 = LED off, in this order:
|
||||
// 74HC595 pin Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7
|
||||
// Mapping to a,b,c,d,e,f,g of Seven-Segment LED
|
||||
byte seven_seg_digits[10] = { B11111100, // = 0
|
||||
B01100000, // = 1
|
||||
B11011010, // = 2
|
||||
B11110010, // = 3
|
||||
B01100110, // = 4
|
||||
B10110110, // = 5
|
||||
B10111110, // = 6
|
||||
B11100000, // = 7
|
||||
B11111110, // = 8
|
||||
B11100110 // = 9
|
||||
};
|
||||
|
||||
// connect to the ST_CP of 74HC595 (pin 3,latch pin)
|
||||
int latchPin = 3;
|
||||
// connect to the SH_CP of 74HC595 (pin 4, clock pin)
|
||||
int clockPin = 4;
|
||||
// connect to the DS of 74HC595 (pin 2)
|
||||
int dataPin = 2;
|
||||
|
||||
void setup() {
|
||||
// Set latchPin, clockPin, dataPin as output
|
||||
pinMode(latchPin, OUTPUT);
|
||||
pinMode(clockPin, OUTPUT);
|
||||
pinMode(dataPin, OUTPUT);
|
||||
}
|
||||
|
||||
// display a number on the digital segment display
|
||||
void sevenSegWrite(byte digit) {
|
||||
// set the latchPin to low potential, before sending data
|
||||
digitalWrite(latchPin, LOW);
|
||||
|
||||
// the original data (bit pattern)
|
||||
shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[digit]);
|
||||
|
||||
// set the latchPin to high potential, after sending data
|
||||
digitalWrite(latchPin, HIGH);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// count from 9 to 0
|
||||
for (byte digit = 10; digit > 0; --digit) {
|
||||
delay(1000);
|
||||
sevenSegWrite(digit - 1);
|
||||
}
|
||||
|
||||
// suspend 4 seconds
|
||||
delay(3000);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.12
|
||||
|
||||
int latch=9; //74HC595 pin 9 STCP
|
||||
int clock=10; //74HC595 pin 10 SHCP
|
||||
int data=8; //74HC595 pin 8 DS
|
||||
|
||||
unsigned char table[]=
|
||||
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c
|
||||
,0x39,0x5e,0x79,0x71,0x00};
|
||||
|
||||
void setup() {
|
||||
pinMode(latch,OUTPUT);
|
||||
pinMode(clock,OUTPUT);
|
||||
pinMode(data,OUTPUT);
|
||||
}
|
||||
void Display(unsigned char num)
|
||||
{
|
||||
|
||||
digitalWrite(latch,LOW);
|
||||
shiftOut(data,clock,MSBFIRST,table[num]);
|
||||
digitalWrite(latch,HIGH);
|
||||
|
||||
}
|
||||
void loop() {
|
||||
Display(1);
|
||||
delay(500);
|
||||
Display(2);
|
||||
delay(500);
|
||||
Display(3);
|
||||
delay(500);
|
||||
Display(4);
|
||||
delay(500);
|
||||
Display(5);
|
||||
delay(500);
|
||||
Display(6);
|
||||
delay(500);
|
||||
Display(7);
|
||||
delay(500);
|
||||
Display(8);
|
||||
delay(500);
|
||||
Display(9);
|
||||
delay(500);
|
||||
Display(10);
|
||||
delay(500);
|
||||
Display(11);
|
||||
delay(500);
|
||||
Display(12);
|
||||
delay(500);
|
||||
Display(13);
|
||||
delay(500);
|
||||
Display(14);
|
||||
delay(500);
|
||||
Display(15);
|
||||
delay(500);
|
||||
}
|
74
projects/elegoo-kit-lessons/Lesson 21 DC Motors/DC_Motor/DC_Motor.ino
Executable file
74
projects/elegoo-kit-lessons/Lesson 21 DC Motors/DC_Motor/DC_Motor.ino
Executable file
@ -0,0 +1,74 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.12
|
||||
|
||||
/************************
|
||||
Exercise the motor using
|
||||
the L293D chip
|
||||
************************/
|
||||
|
||||
#define ENABLE 5
|
||||
#define DIRA 3
|
||||
#define DIRB 4
|
||||
|
||||
int i;
|
||||
|
||||
void setup() {
|
||||
//---set pin direction
|
||||
pinMode(ENABLE,OUTPUT);
|
||||
pinMode(DIRA,OUTPUT);
|
||||
pinMode(DIRB,OUTPUT);
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//---back and forth example
|
||||
Serial.println("One way, then reverse");
|
||||
digitalWrite(ENABLE,HIGH); // enable on
|
||||
for (i=0;i<5;i++) {
|
||||
digitalWrite(DIRA,HIGH); //one way
|
||||
digitalWrite(DIRB,LOW);
|
||||
delay(500);
|
||||
digitalWrite(DIRA,LOW); //reverse
|
||||
digitalWrite(DIRB,HIGH);
|
||||
delay(500);
|
||||
}
|
||||
digitalWrite(ENABLE,LOW); // disable
|
||||
delay(2000);
|
||||
|
||||
Serial.println("fast Slow example");
|
||||
//---fast/slow stop example
|
||||
digitalWrite(ENABLE,HIGH); //enable on
|
||||
digitalWrite(DIRA,HIGH); //one way
|
||||
digitalWrite(DIRB,LOW);
|
||||
delay(3000);
|
||||
digitalWrite(ENABLE,LOW); //slow stop
|
||||
delay(1000);
|
||||
digitalWrite(ENABLE,HIGH); //enable on
|
||||
digitalWrite(DIRA,LOW); //one way
|
||||
digitalWrite(DIRB,HIGH);
|
||||
delay(3000);
|
||||
digitalWrite(DIRA,LOW); //fast stop
|
||||
delay(2000);
|
||||
|
||||
Serial.println("PWM full then slow");
|
||||
//---PWM example, full speed then slow
|
||||
analogWrite(ENABLE,255); //enable on
|
||||
digitalWrite(DIRA,HIGH); //one way
|
||||
digitalWrite(DIRB,LOW);
|
||||
delay(2000);
|
||||
analogWrite(ENABLE,180); //half speed
|
||||
delay(2000);
|
||||
analogWrite(ENABLE,128); //half speed
|
||||
delay(2000);
|
||||
analogWrite(ENABLE,50); //half speed
|
||||
delay(2000);
|
||||
analogWrite(ENABLE,128); //half speed
|
||||
delay(2000);
|
||||
analogWrite(ENABLE,180); //half speed
|
||||
delay(2000);
|
||||
analogWrite(ENABLE,255); //half speed
|
||||
delay(2000);
|
||||
digitalWrite(ENABLE,LOW); //all done
|
||||
delay(10000);
|
||||
}
|
||||
|
49
projects/elegoo-kit-lessons/Lesson 22 Relay/Relay/Relay.ino
Executable file
49
projects/elegoo-kit-lessons/Lesson 22 Relay/Relay/Relay.ino
Executable file
@ -0,0 +1,49 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.12
|
||||
|
||||
/************************
|
||||
Exercise the motor using
|
||||
the L293D chip
|
||||
************************/
|
||||
|
||||
#define ENABLE 5
|
||||
#define DIRA 3
|
||||
#define DIRB 4
|
||||
|
||||
int i;
|
||||
|
||||
void setup() {
|
||||
//---set pin direction
|
||||
pinMode(ENABLE,OUTPUT);
|
||||
pinMode(DIRA,OUTPUT);
|
||||
pinMode(DIRB,OUTPUT);
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
//---back and forth example
|
||||
Serial.println("One way, then reverse");
|
||||
digitalWrite(ENABLE,HIGH); // enable on
|
||||
for (i=0;i<5;i++) {
|
||||
digitalWrite(DIRA,HIGH); //one way
|
||||
digitalWrite(DIRB,LOW);
|
||||
delay(750);
|
||||
digitalWrite(DIRA,LOW); //reverse
|
||||
digitalWrite(DIRB,HIGH);
|
||||
delay(750);
|
||||
}
|
||||
digitalWrite(ENABLE,LOW); // disable
|
||||
delay(3000);
|
||||
for (i=0;i<5;i++) {
|
||||
digitalWrite(DIRA,HIGH); //one way
|
||||
digitalWrite(DIRB,LOW);
|
||||
delay(750);
|
||||
digitalWrite(DIRA,LOW); //reverse
|
||||
digitalWrite(DIRB,HIGH);
|
||||
delay(750);
|
||||
}
|
||||
digitalWrite(ENABLE,LOW); // disable
|
||||
delay(3000);
|
||||
}
|
||||
|
BIN
projects/elegoo-kit-lessons/Lesson 23 Stepper Motor/Stepper.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 23 Stepper Motor/Stepper.zip
Executable file
Binary file not shown.
@ -0,0 +1,40 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.12
|
||||
|
||||
/*
|
||||
Stepper Motor Control - one revolution
|
||||
|
||||
This program drives a unipolar or bipolar stepper motor.
|
||||
The motor is attached to digital pins 8 - 11 of the Arduino.
|
||||
|
||||
The motor should revolve one revolution in one direction, then
|
||||
one revolution in the other direction.
|
||||
|
||||
*/
|
||||
|
||||
#include <Stepper.h>
|
||||
|
||||
const int stepsPerRevolution = 1500; // change this to fit the number of steps per revolution
|
||||
|
||||
// initialize the stepper library on pins 8 through 11:
|
||||
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
|
||||
|
||||
void setup() {
|
||||
// set the speed at 20 rpm:
|
||||
myStepper.setSpeed(20);
|
||||
// initialize the serial port:
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// step one revolution in one direction:
|
||||
Serial.println("clockwise");
|
||||
myStepper.step(stepsPerRevolution);
|
||||
delay(500);
|
||||
|
||||
// step one revolution in the other direction:
|
||||
Serial.println("counterclockwise");
|
||||
myStepper.step(-stepsPerRevolution);
|
||||
delay(500);
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,58 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.12
|
||||
|
||||
#include "Stepper.h"
|
||||
#include "IRremote.h"
|
||||
|
||||
/*----- Variables, Pins -----*/
|
||||
#define STEPS 32 // Number of steps per revolution of Internal shaft
|
||||
int Steps2Take; // 2048 = 1 Revolution
|
||||
int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 6
|
||||
|
||||
/*-----( Declare objects )-----*/
|
||||
// Setup of proper sequencing for Motor Driver Pins
|
||||
// In1, In2, In3, In4 in the sequence 1-3-2-4
|
||||
|
||||
Stepper small_stepper(STEPS, 8, 10, 9, 11);
|
||||
IRrecv irrecv(receiver); // create instance of 'irrecv'
|
||||
decode_results results; // create instance of 'decode_results'
|
||||
|
||||
void setup()
|
||||
{
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (irrecv.decode(&results)) // have we received an IR signal?
|
||||
|
||||
{
|
||||
switch(results.value)
|
||||
|
||||
{
|
||||
|
||||
case 0xFFA857: // VOL+ button pressed
|
||||
small_stepper.setSpeed(500); //Max seems to be 500
|
||||
Steps2Take = 2048; // Rotate CW
|
||||
small_stepper.step(Steps2Take);
|
||||
delay(2000);
|
||||
break;
|
||||
|
||||
case 0xFF629D: // VOL- button pressed
|
||||
small_stepper.setSpeed(500);
|
||||
Steps2Take = -2048; // Rotate CCW
|
||||
small_stepper.step(Steps2Take);
|
||||
delay(2000);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
irrecv.resume(); // receive the next value
|
||||
digitalWrite(8, LOW);
|
||||
digitalWrite(9, LOW);
|
||||
digitalWrite(10, LOW);
|
||||
digitalWrite(11, LOW);
|
||||
}
|
||||
|
||||
|
||||
}/* --end main loop -- */
|
83
projects/elegoo-kit-lessons/Lesson 4 RGB LED/RGB_LED/RGB_LED.ino
Executable file
83
projects/elegoo-kit-lessons/Lesson 4 RGB LED/RGB_LED/RGB_LED.ino
Executable file
@ -0,0 +1,83 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.8
|
||||
|
||||
// Define Pins
|
||||
#define BLUE 3
|
||||
#define GREEN 5
|
||||
#define RED 6
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(RED, OUTPUT);
|
||||
pinMode(GREEN, OUTPUT);
|
||||
pinMode(BLUE, OUTPUT);
|
||||
digitalWrite(RED, HIGH);
|
||||
digitalWrite(GREEN, LOW);
|
||||
digitalWrite(BLUE, LOW);
|
||||
}
|
||||
|
||||
// define variables
|
||||
int redValue;
|
||||
int greenValue;
|
||||
int blueValue;
|
||||
|
||||
// main loop
|
||||
void loop()
|
||||
{
|
||||
#define delayTime 10 // fading time between colors
|
||||
|
||||
redValue = 255; // choose a value between 1 and 255 to change the color.
|
||||
greenValue = 0;
|
||||
blueValue = 0;
|
||||
|
||||
// this is unnecessary as we've either turned on RED in SETUP
|
||||
// or in the previous loop ... regardless, this turns RED off
|
||||
// analogWrite(RED, 0);
|
||||
// delay(1000);
|
||||
|
||||
for(int i = 0; i < 255; i += 1) // fades out red bring green full when i=255
|
||||
{
|
||||
redValue -= 1;
|
||||
greenValue += 1;
|
||||
// The following was reversed, counting in the wrong directions
|
||||
// analogWrite(RED, 255 - redValue);
|
||||
// analogWrite(GREEN, 255 - greenValue);
|
||||
analogWrite(RED, redValue);
|
||||
analogWrite(GREEN, greenValue);
|
||||
delay(delayTime);
|
||||
}
|
||||
|
||||
redValue = 0;
|
||||
greenValue = 255;
|
||||
blueValue = 0;
|
||||
|
||||
for(int i = 0; i < 255; i += 1) // fades out green bring blue full when i=255
|
||||
{
|
||||
greenValue -= 1;
|
||||
blueValue += 1;
|
||||
// The following was reversed, counting in the wrong directions
|
||||
// analogWrite(GREEN, 255 - greenValue);
|
||||
// analogWrite(BLUE, 255 - blueValue);
|
||||
analogWrite(GREEN, greenValue);
|
||||
analogWrite(BLUE, blueValue);
|
||||
delay(delayTime);
|
||||
}
|
||||
|
||||
redValue = 0;
|
||||
greenValue = 0;
|
||||
blueValue = 255;
|
||||
|
||||
for(int i = 0; i < 255; i += 1) // fades out blue bring red full when i=255
|
||||
{
|
||||
// The following code has been rearranged to match the other two similar sections
|
||||
blueValue -= 1;
|
||||
redValue += 1;
|
||||
// The following was reversed, counting in the wrong directions
|
||||
// analogWrite(BLUE, 255 - blueValue);
|
||||
// analogWrite(RED, 255 - redValue);
|
||||
analogWrite(BLUE, blueValue);
|
||||
analogWrite(RED, redValue);
|
||||
delay(delayTime);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.08
|
||||
|
||||
int ledPin = 5;
|
||||
int buttonApin = 9;
|
||||
int buttonBpin = 8;
|
||||
|
||||
byte leds = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(buttonApin, INPUT_PULLUP);
|
||||
pinMode(buttonBpin, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (digitalRead(buttonApin) == LOW)
|
||||
{
|
||||
digitalWrite(ledPin, HIGH);
|
||||
}
|
||||
if (digitalRead(buttonBpin) == LOW)
|
||||
{
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
}
|
31
projects/elegoo-kit-lessons/Lesson 6 Making Sounds/active/active.ino
Executable file
31
projects/elegoo-kit-lessons/Lesson 6 Making Sounds/active/active.ino
Executable file
@ -0,0 +1,31 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.08
|
||||
|
||||
int buzzer = 12;//the pin of the active buzzer
|
||||
void setup()
|
||||
{
|
||||
pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
unsigned char i;
|
||||
while(1)
|
||||
{
|
||||
//output an frequency
|
||||
for(i=0;i<80;i++)
|
||||
{
|
||||
digitalWrite(buzzer,HIGH);
|
||||
delay(1);//wait for 1ms
|
||||
digitalWrite(buzzer,LOW);
|
||||
delay(1);//wait for 1ms
|
||||
}
|
||||
//output another frequency
|
||||
for(i=0;i<100;i++)
|
||||
{
|
||||
digitalWrite(buzzer,HIGH);
|
||||
delay(2);//wait for 2ms
|
||||
digitalWrite(buzzer,LOW);
|
||||
delay(2);//wait for 2ms
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.08
|
||||
|
||||
#include "pitches.h"
|
||||
|
||||
// notes in the melody:
|
||||
int melody[] = {
|
||||
NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_B5, NOTE_C6};
|
||||
int duration = 500; // 500 miliseconds
|
||||
|
||||
void setup() {
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (int thisNote = 0; thisNote < 8; thisNote++) {
|
||||
// pin8 output the voice, every scale is 0.5 sencond
|
||||
tone(8, melody[thisNote], duration);
|
||||
|
||||
// Output the voice after several minutes
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// restart after two seconds
|
||||
delay(2000);
|
||||
}
|
BIN
projects/elegoo-kit-lessons/Lesson 7 Passive Buzzer/pitches.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 7 Passive Buzzer/pitches.zip
Executable file
Binary file not shown.
26
projects/elegoo-kit-lessons/Lesson 8 Ball Switch/Ball_Switch/Ball_Switch.ino
Executable file
26
projects/elegoo-kit-lessons/Lesson 8 Ball Switch/Ball_Switch/Ball_Switch.ino
Executable file
@ -0,0 +1,26 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.08
|
||||
/*****************************************/
|
||||
const int ledPin = 13;//the led attach to
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(ledPin,OUTPUT);//initialize the ledPin as an output
|
||||
pinMode(2,INPUT);
|
||||
digitalWrite(2, HIGH);
|
||||
}
|
||||
/******************************************/
|
||||
void loop()
|
||||
{
|
||||
int digitalVal = digitalRead(2);
|
||||
if(HIGH == digitalVal)
|
||||
{
|
||||
digitalWrite(ledPin,LOW);//turn the led off
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(ledPin,HIGH);//turn the led on
|
||||
}
|
||||
}
|
||||
/**********************************************/
|
||||
|
BIN
projects/elegoo-kit-lessons/Lesson 9 Servo/.DS_Store
vendored
Normal file
BIN
projects/elegoo-kit-lessons/Lesson 9 Servo/.DS_Store
vendored
Normal file
Binary file not shown.
25
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/README.adoc
Executable file
25
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/README.adoc
Executable file
@ -0,0 +1,25 @@
|
||||
= Servo Library for Arduino =
|
||||
|
||||
This library allows an Arduino board to control RC (hobby) servo motors.
|
||||
|
||||
For more information about this library please visit us at
|
||||
http://www.arduino.cc/en/Reference/Servo
|
||||
|
||||
== License ==
|
||||
|
||||
Copyright (c) 2013 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
27
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/examples/Knob/Knob.ino
Executable file
27
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/examples/Knob/Knob.ino
Executable file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Controlling a servo position using a potentiometer (variable resistor)
|
||||
by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
|
||||
|
||||
modified on 8 Nov 2013
|
||||
by Scott Fitzgerald
|
||||
http://www.arduino.cc/en/Tutorial/Knob
|
||||
*/
|
||||
|
||||
#include <Servo.h>
|
||||
|
||||
Servo myservo; // create servo object to control a servo
|
||||
|
||||
int potpin = 0; // analog pin used to connect the potentiometer
|
||||
int val; // variable to read the value from the analog pin
|
||||
|
||||
void setup() {
|
||||
myservo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
}
|
||||
|
||||
void loop() {
|
||||
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
|
||||
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
|
||||
myservo.write(val); // sets the servo position according to the scaled value
|
||||
delay(15); // waits for the servo to get there
|
||||
}
|
||||
|
32
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/examples/Sweep/Sweep.ino
Executable file
32
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/examples/Sweep/Sweep.ino
Executable file
@ -0,0 +1,32 @@
|
||||
/* Sweep
|
||||
by BARRAGAN <http://barraganstudio.com>
|
||||
This example code is in the public domain.
|
||||
|
||||
modified 8 Nov 2013
|
||||
by Scott Fitzgerald
|
||||
http://www.arduino.cc/en/Tutorial/Sweep
|
||||
*/
|
||||
|
||||
#include <Servo.h>
|
||||
|
||||
Servo myservo; // create servo object to control a servo
|
||||
// twelve servo objects can be created on most boards
|
||||
|
||||
int pos = 0; // variable to store the servo position
|
||||
|
||||
void setup() {
|
||||
myservo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
|
||||
// in steps of 1 degree
|
||||
myservo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
delay(15); // waits 15ms for the servo to reach the position
|
||||
}
|
||||
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
|
||||
myservo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
delay(15); // waits 15ms for the servo to reach the position
|
||||
}
|
||||
}
|
||||
|
24
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/keywords.txt
Executable file
24
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/keywords.txt
Executable file
@ -0,0 +1,24 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map Servo
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
Servo KEYWORD1 Servo
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
attach KEYWORD2
|
||||
detach KEYWORD2
|
||||
write KEYWORD2
|
||||
read KEYWORD2
|
||||
attached KEYWORD2
|
||||
writeMicroseconds KEYWORD2
|
||||
readMicroseconds KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
9
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/library.properties
Executable file
9
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/library.properties
Executable file
@ -0,0 +1,9 @@
|
||||
name=Servo
|
||||
version=1.1.2
|
||||
author=Michael Margolis, Arduino
|
||||
maintainer=Arduino <info@arduino.cc>
|
||||
sentence=Allows Arduino/Genuino boards to control a variety of servo motors.
|
||||
paragraph=This library can control a great number of servos.<br />It makes careful use of timers: the library can control 12 servos using only 1 timer.<br />On the Arduino Due you can control up to 60 servos.<br />
|
||||
category=Device Control
|
||||
url=http://www.arduino.cc/en/Reference/Servo
|
||||
architectures=avr,sam,samd
|
112
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/Servo.h
Executable file
112
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/Servo.h
Executable file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
|
||||
Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
A servo is activated by creating an instance of the Servo class passing
|
||||
the desired pin to the attach() method.
|
||||
The servos are pulsed in the background using the value most recently
|
||||
written using the write() method.
|
||||
|
||||
Note that analogWrite of PWM on pins associated with the timer are
|
||||
disabled when the first servo is attached.
|
||||
Timers are seized as needed in groups of 12 servos - 24 servos use two
|
||||
timers, 48 servos will use four.
|
||||
The sequence used to sieze timers is defined in timers.h
|
||||
|
||||
The methods are:
|
||||
|
||||
Servo - Class for manipulating servo motors connected to Arduino pins.
|
||||
|
||||
attach(pin ) - Attaches a servo motor to an i/o pin.
|
||||
attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds
|
||||
default min is 544, max is 2400
|
||||
|
||||
write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds)
|
||||
writeMicroseconds() - Sets the servo pulse width in microseconds
|
||||
read() - Gets the last written servo pulse width as an angle between 0 and 180.
|
||||
readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
|
||||
attached() - Returns true if there is a servo attached.
|
||||
detach() - Stops an attached servos from pulsing its i/o pin.
|
||||
*/
|
||||
|
||||
#ifndef Servo_h
|
||||
#define Servo_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Defines for 16 bit timers used with Servo library
|
||||
*
|
||||
* If _useTimerX is defined then TimerX is a 16 bit timer on the current board
|
||||
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
|
||||
* _Nbr_16timers indicates how many 16 bit timers are available.
|
||||
*/
|
||||
|
||||
// Architecture specific include
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
#include "avr/ServoTimers.h"
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
#include "sam/ServoTimers.h"
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#include "samd/ServoTimers.h"
|
||||
#else
|
||||
#error "This library only supports boards with an AVR, SAM or SAMD processor."
|
||||
#endif
|
||||
|
||||
#define Servo_VERSION 2 // software version of this library
|
||||
|
||||
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
|
||||
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
|
||||
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
|
||||
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
|
||||
|
||||
#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
|
||||
#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
|
||||
|
||||
#define INVALID_SERVO 255 // flag indicating an invalid servo index
|
||||
|
||||
typedef struct {
|
||||
uint8_t nbr :6 ; // a pin number from 0 to 63
|
||||
uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false
|
||||
} ServoPin_t ;
|
||||
|
||||
typedef struct {
|
||||
ServoPin_t Pin;
|
||||
volatile unsigned int ticks;
|
||||
} servo_t;
|
||||
|
||||
class Servo
|
||||
{
|
||||
public:
|
||||
Servo();
|
||||
uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
|
||||
uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes.
|
||||
void detach();
|
||||
void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
|
||||
void writeMicroseconds(int value); // Write pulse width in microseconds
|
||||
int read(); // returns current pulse width as an angle between 0 and 180 degrees
|
||||
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
|
||||
bool attached(); // return true if this servo is attached, otherwise false
|
||||
private:
|
||||
uint8_t servoIndex; // index into the channel data for this servo
|
||||
int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH
|
||||
int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
|
||||
};
|
||||
|
||||
#endif
|
317
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/avr/Servo.cpp
Executable file
317
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/avr/Servo.cpp
Executable file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
Servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
|
||||
Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "Servo.h"
|
||||
|
||||
#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009
|
||||
#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
|
||||
|
||||
|
||||
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009
|
||||
|
||||
//#define NBR_TIMERS (MAX_SERVOS / SERVOS_PER_TIMER)
|
||||
|
||||
static servo_t servos[MAX_SERVOS]; // static array of servo structures
|
||||
static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
|
||||
|
||||
uint8_t ServoCount = 0; // the total number of attached servos
|
||||
|
||||
|
||||
// convenience macros
|
||||
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo
|
||||
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer
|
||||
#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel
|
||||
#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
|
||||
|
||||
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
|
||||
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
|
||||
|
||||
/************ static functions common to all instances ***********************/
|
||||
|
||||
static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA)
|
||||
{
|
||||
if( Channel[timer] < 0 )
|
||||
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
|
||||
else{
|
||||
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true )
|
||||
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated
|
||||
}
|
||||
|
||||
Channel[timer]++; // increment to the next channel
|
||||
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
|
||||
*OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks;
|
||||
if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated
|
||||
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
|
||||
}
|
||||
else {
|
||||
// finished all channels so wait for the refresh period to expire before starting over
|
||||
if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed
|
||||
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
|
||||
else
|
||||
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
|
||||
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
|
||||
// Interrupt handlers for Arduino
|
||||
#if defined(_useTimer1)
|
||||
SIGNAL (TIMER1_COMPA_vect)
|
||||
{
|
||||
handle_interrupts(_timer1, &TCNT1, &OCR1A);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_useTimer3)
|
||||
SIGNAL (TIMER3_COMPA_vect)
|
||||
{
|
||||
handle_interrupts(_timer3, &TCNT3, &OCR3A);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_useTimer4)
|
||||
SIGNAL (TIMER4_COMPA_vect)
|
||||
{
|
||||
handle_interrupts(_timer4, &TCNT4, &OCR4A);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_useTimer5)
|
||||
SIGNAL (TIMER5_COMPA_vect)
|
||||
{
|
||||
handle_interrupts(_timer5, &TCNT5, &OCR5A);
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined WIRING
|
||||
// Interrupt handlers for Wiring
|
||||
#if defined(_useTimer1)
|
||||
void Timer1Service()
|
||||
{
|
||||
handle_interrupts(_timer1, &TCNT1, &OCR1A);
|
||||
}
|
||||
#endif
|
||||
#if defined(_useTimer3)
|
||||
void Timer3Service()
|
||||
{
|
||||
handle_interrupts(_timer3, &TCNT3, &OCR3A);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static void initISR(timer16_Sequence_t timer)
|
||||
{
|
||||
#if defined (_useTimer1)
|
||||
if(timer == _timer1) {
|
||||
TCCR1A = 0; // normal counting mode
|
||||
TCCR1B = _BV(CS11); // set prescaler of 8
|
||||
TCNT1 = 0; // clear the timer count
|
||||
#if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__)
|
||||
TIFR |= _BV(OCF1A); // clear any pending interrupts;
|
||||
TIMSK |= _BV(OCIE1A) ; // enable the output compare interrupt
|
||||
#else
|
||||
// here if not ATmega8 or ATmega128
|
||||
TIFR1 |= _BV(OCF1A); // clear any pending interrupts;
|
||||
TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt
|
||||
#endif
|
||||
#if defined(WIRING)
|
||||
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_useTimer3)
|
||||
if(timer == _timer3) {
|
||||
TCCR3A = 0; // normal counting mode
|
||||
TCCR3B = _BV(CS31); // set prescaler of 8
|
||||
TCNT3 = 0; // clear the timer count
|
||||
#if defined(__AVR_ATmega128__)
|
||||
TIFR |= _BV(OCF3A); // clear any pending interrupts;
|
||||
ETIMSK |= _BV(OCIE3A); // enable the output compare interrupt
|
||||
#else
|
||||
TIFR3 = _BV(OCF3A); // clear any pending interrupts;
|
||||
TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt
|
||||
#endif
|
||||
#if defined(WIRING)
|
||||
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_useTimer4)
|
||||
if(timer == _timer4) {
|
||||
TCCR4A = 0; // normal counting mode
|
||||
TCCR4B = _BV(CS41); // set prescaler of 8
|
||||
TCNT4 = 0; // clear the timer count
|
||||
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
|
||||
TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_useTimer5)
|
||||
if(timer == _timer5) {
|
||||
TCCR5A = 0; // normal counting mode
|
||||
TCCR5B = _BV(CS51); // set prescaler of 8
|
||||
TCNT5 = 0; // clear the timer count
|
||||
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
|
||||
TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void finISR(timer16_Sequence_t timer)
|
||||
{
|
||||
//disable use of the given timer
|
||||
#if defined WIRING // Wiring
|
||||
if(timer == _timer1) {
|
||||
#if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
|
||||
TIMSK1 &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt
|
||||
#else
|
||||
TIMSK &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt
|
||||
#endif
|
||||
timerDetach(TIMER1OUTCOMPAREA_INT);
|
||||
}
|
||||
else if(timer == _timer3) {
|
||||
#if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
|
||||
TIMSK3 &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt
|
||||
#else
|
||||
ETIMSK &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt
|
||||
#endif
|
||||
timerDetach(TIMER3OUTCOMPAREA_INT);
|
||||
}
|
||||
#else
|
||||
//For arduino - in future: call here to a currently undefined function to reset the timer
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean isTimerActive(timer16_Sequence_t timer)
|
||||
{
|
||||
// returns true if any servo is active on this timer
|
||||
for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) {
|
||||
if(SERVO(timer,channel).Pin.isActive == true)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/****************** end of static functions ******************************/
|
||||
|
||||
Servo::Servo()
|
||||
{
|
||||
if( ServoCount < MAX_SERVOS) {
|
||||
this->servoIndex = ServoCount++; // assign a servo index to this instance
|
||||
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
|
||||
}
|
||||
else
|
||||
this->servoIndex = INVALID_SERVO ; // too many servos
|
||||
}
|
||||
|
||||
uint8_t Servo::attach(int pin)
|
||||
{
|
||||
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
|
||||
}
|
||||
|
||||
uint8_t Servo::attach(int pin, int min, int max)
|
||||
{
|
||||
if(this->servoIndex < MAX_SERVOS ) {
|
||||
pinMode( pin, OUTPUT) ; // set servo pin to output
|
||||
servos[this->servoIndex].Pin.nbr = pin;
|
||||
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
|
||||
this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
|
||||
this->max = (MAX_PULSE_WIDTH - max)/4;
|
||||
// initialize the timer if it has not already been initialized
|
||||
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||
if(isTimerActive(timer) == false)
|
||||
initISR(timer);
|
||||
servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
|
||||
}
|
||||
return this->servoIndex ;
|
||||
}
|
||||
|
||||
void Servo::detach()
|
||||
{
|
||||
servos[this->servoIndex].Pin.isActive = false;
|
||||
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||
if(isTimerActive(timer) == false) {
|
||||
finISR(timer);
|
||||
}
|
||||
}
|
||||
|
||||
void Servo::write(int value)
|
||||
{
|
||||
if(value < MIN_PULSE_WIDTH)
|
||||
{ // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
|
||||
if(value < 0) value = 0;
|
||||
if(value > 180) value = 180;
|
||||
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
|
||||
}
|
||||
this->writeMicroseconds(value);
|
||||
}
|
||||
|
||||
void Servo::writeMicroseconds(int value)
|
||||
{
|
||||
// calculate and store the values for the given channel
|
||||
byte channel = this->servoIndex;
|
||||
if( (channel < MAX_SERVOS) ) // ensure channel is valid
|
||||
{
|
||||
if( value < SERVO_MIN() ) // ensure pulse width is valid
|
||||
value = SERVO_MIN();
|
||||
else if( value > SERVO_MAX() )
|
||||
value = SERVO_MAX();
|
||||
|
||||
value = value - TRIM_DURATION;
|
||||
value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009
|
||||
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
servos[channel].ticks = value;
|
||||
SREG = oldSREG;
|
||||
}
|
||||
}
|
||||
|
||||
int Servo::read() // return the value as degrees
|
||||
{
|
||||
return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180);
|
||||
}
|
||||
|
||||
int Servo::readMicroseconds()
|
||||
{
|
||||
unsigned int pulsewidth;
|
||||
if( this->servoIndex != INVALID_SERVO )
|
||||
pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION ; // 12 aug 2009
|
||||
else
|
||||
pulsewidth = 0;
|
||||
|
||||
return pulsewidth;
|
||||
}
|
||||
|
||||
bool Servo::attached()
|
||||
{
|
||||
return servos[this->servoIndex].Pin.isActive ;
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ARCH_AVR
|
||||
|
59
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/avr/ServoTimers.h
Executable file
59
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/avr/ServoTimers.h
Executable file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
|
||||
Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines for 16 bit timers used with Servo library
|
||||
*
|
||||
* If _useTimerX is defined then TimerX is a 16 bit timer on the current board
|
||||
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
|
||||
* _Nbr_16timers indicates how many 16 bit timers are available.
|
||||
*/
|
||||
|
||||
/**
|
||||
* AVR Only definitions
|
||||
* --------------------
|
||||
*/
|
||||
|
||||
// Say which 16 bit timers can be used and in what order
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define _useTimer5
|
||||
#define _useTimer1
|
||||
#define _useTimer3
|
||||
#define _useTimer4
|
||||
typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t;
|
||||
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define _useTimer1
|
||||
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t;
|
||||
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
#define _useTimer3
|
||||
#define _useTimer1
|
||||
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t;
|
||||
|
||||
#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__)
|
||||
#define _useTimer3
|
||||
#define _useTimer1
|
||||
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t;
|
||||
|
||||
#else // everything else
|
||||
#define _useTimer1
|
||||
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t;
|
||||
#endif
|
||||
|
283
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/sam/Servo.cpp
Executable file
283
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/sam/Servo.cpp
Executable file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
Copyright (c) 2013 Arduino LLC. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAM)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Servo.h>
|
||||
|
||||
#define usToTicks(_us) (( clockCyclesPerMicrosecond() * _us) / 32) // converts microseconds to tick
|
||||
#define ticksToUs(_ticks) (( (unsigned)_ticks * 32)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
|
||||
|
||||
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays
|
||||
|
||||
static servo_t servos[MAX_SERVOS]; // static array of servo structures
|
||||
|
||||
uint8_t ServoCount = 0; // the total number of attached servos
|
||||
|
||||
static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
|
||||
|
||||
// convenience macros
|
||||
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo
|
||||
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer
|
||||
#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel
|
||||
#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
|
||||
|
||||
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
|
||||
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
|
||||
|
||||
/************ static functions common to all instances ***********************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Interrupt handler for the TC0 channel 1.
|
||||
//------------------------------------------------------------------------------
|
||||
void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel);
|
||||
#if defined (_useTimer1)
|
||||
void HANDLER_FOR_TIMER1(void) {
|
||||
Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1);
|
||||
}
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
void HANDLER_FOR_TIMER2(void) {
|
||||
Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2);
|
||||
}
|
||||
#endif
|
||||
#if defined (_useTimer3)
|
||||
void HANDLER_FOR_TIMER3(void) {
|
||||
Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3);
|
||||
}
|
||||
#endif
|
||||
#if defined (_useTimer4)
|
||||
void HANDLER_FOR_TIMER4(void) {
|
||||
Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4);
|
||||
}
|
||||
#endif
|
||||
#if defined (_useTimer5)
|
||||
void HANDLER_FOR_TIMER5(void) {
|
||||
Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel)
|
||||
{
|
||||
// clear interrupt
|
||||
tc->TC_CHANNEL[channel].TC_SR;
|
||||
if (Channel[timer] < 0) {
|
||||
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
|
||||
} else {
|
||||
if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true) {
|
||||
digitalWrite(SERVO(timer,Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
|
||||
}
|
||||
}
|
||||
|
||||
Channel[timer]++; // increment to the next channel
|
||||
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
|
||||
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
|
||||
if(SERVO(timer,Channel[timer]).Pin.isActive == true) { // check if activated
|
||||
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
|
||||
}
|
||||
}
|
||||
else {
|
||||
// finished all channels so wait for the refresh period to expire before starting over
|
||||
if( (tc->TC_CHANNEL[channel].TC_CV) + 4 < usToTicks(REFRESH_INTERVAL) ) { // allow a few ticks to ensure the next OCR1A not missed
|
||||
tc->TC_CHANNEL[channel].TC_RA = (unsigned int)usToTicks(REFRESH_INTERVAL);
|
||||
}
|
||||
else {
|
||||
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed
|
||||
}
|
||||
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
|
||||
}
|
||||
}
|
||||
|
||||
static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn)
|
||||
{
|
||||
pmc_enable_periph_clk(id);
|
||||
TC_Configure(tc, channel,
|
||||
TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32
|
||||
TC_CMR_WAVE | // Waveform mode
|
||||
TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
|
||||
|
||||
/* 84MHz, MCK/32, for 1.5ms: 3937 */
|
||||
TC_SetRA(tc, channel, 2625); // 1ms
|
||||
|
||||
/* Configure and enable interrupt */
|
||||
NVIC_EnableIRQ(irqn);
|
||||
// TC_IER_CPAS: RA Compare
|
||||
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS;
|
||||
|
||||
// Enables the timer clock and performs a software reset to start the counting
|
||||
TC_Start(tc, channel);
|
||||
}
|
||||
|
||||
static void initISR(timer16_Sequence_t timer)
|
||||
{
|
||||
#if defined (_useTimer1)
|
||||
if (timer == _timer1)
|
||||
_initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
if (timer == _timer2)
|
||||
_initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
|
||||
#endif
|
||||
#if defined (_useTimer3)
|
||||
if (timer == _timer3)
|
||||
_initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
|
||||
#endif
|
||||
#if defined (_useTimer4)
|
||||
if (timer == _timer4)
|
||||
_initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
|
||||
#endif
|
||||
#if defined (_useTimer5)
|
||||
if (timer == _timer5)
|
||||
_initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void finISR(timer16_Sequence_t timer)
|
||||
{
|
||||
#if defined (_useTimer1)
|
||||
TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1);
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2);
|
||||
#endif
|
||||
#if defined (_useTimer3)
|
||||
TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3);
|
||||
#endif
|
||||
#if defined (_useTimer4)
|
||||
TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4);
|
||||
#endif
|
||||
#if defined (_useTimer5)
|
||||
TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static boolean isTimerActive(timer16_Sequence_t timer)
|
||||
{
|
||||
// returns true if any servo is active on this timer
|
||||
for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) {
|
||||
if(SERVO(timer,channel).Pin.isActive == true)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************** end of static functions ******************************/
|
||||
|
||||
Servo::Servo()
|
||||
{
|
||||
if (ServoCount < MAX_SERVOS) {
|
||||
this->servoIndex = ServoCount++; // assign a servo index to this instance
|
||||
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values
|
||||
} else {
|
||||
this->servoIndex = INVALID_SERVO; // too many servos
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Servo::attach(int pin)
|
||||
{
|
||||
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
|
||||
}
|
||||
|
||||
uint8_t Servo::attach(int pin, int min, int max)
|
||||
{
|
||||
timer16_Sequence_t timer;
|
||||
|
||||
if (this->servoIndex < MAX_SERVOS) {
|
||||
pinMode(pin, OUTPUT); // set servo pin to output
|
||||
servos[this->servoIndex].Pin.nbr = pin;
|
||||
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
|
||||
this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
|
||||
this->max = (MAX_PULSE_WIDTH - max)/4;
|
||||
// initialize the timer if it has not already been initialized
|
||||
timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||
if (isTimerActive(timer) == false) {
|
||||
initISR(timer);
|
||||
}
|
||||
servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
|
||||
}
|
||||
return this->servoIndex;
|
||||
}
|
||||
|
||||
void Servo::detach()
|
||||
{
|
||||
timer16_Sequence_t timer;
|
||||
|
||||
servos[this->servoIndex].Pin.isActive = false;
|
||||
timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||
if(isTimerActive(timer) == false) {
|
||||
finISR(timer);
|
||||
}
|
||||
}
|
||||
|
||||
void Servo::write(int value)
|
||||
{
|
||||
// treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
|
||||
if (value < MIN_PULSE_WIDTH)
|
||||
{
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
else if (value > 180)
|
||||
value = 180;
|
||||
|
||||
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
|
||||
}
|
||||
writeMicroseconds(value);
|
||||
}
|
||||
|
||||
void Servo::writeMicroseconds(int value)
|
||||
{
|
||||
// calculate and store the values for the given channel
|
||||
byte channel = this->servoIndex;
|
||||
if( (channel < MAX_SERVOS) ) // ensure channel is valid
|
||||
{
|
||||
if (value < SERVO_MIN()) // ensure pulse width is valid
|
||||
value = SERVO_MIN();
|
||||
else if (value > SERVO_MAX())
|
||||
value = SERVO_MAX();
|
||||
|
||||
value = value - TRIM_DURATION;
|
||||
value = usToTicks(value); // convert to ticks after compensating for interrupt overhead
|
||||
servos[channel].ticks = value;
|
||||
}
|
||||
}
|
||||
|
||||
int Servo::read() // return the value as degrees
|
||||
{
|
||||
return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180);
|
||||
}
|
||||
|
||||
int Servo::readMicroseconds()
|
||||
{
|
||||
unsigned int pulsewidth;
|
||||
if (this->servoIndex != INVALID_SERVO)
|
||||
pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION;
|
||||
else
|
||||
pulsewidth = 0;
|
||||
|
||||
return pulsewidth;
|
||||
}
|
||||
|
||||
bool Servo::attached()
|
||||
{
|
||||
return servos[this->servoIndex].Pin.isActive;
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ARCH_SAM
|
||||
|
88
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/sam/ServoTimers.h
Executable file
88
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/sam/ServoTimers.h
Executable file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (c) 2013 Arduino LLC. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines for 16 bit timers used with Servo library
|
||||
*
|
||||
* If _useTimerX is defined then TimerX is a 16 bit timer on the current board
|
||||
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
|
||||
* _Nbr_16timers indicates how many 16 bit timers are available.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SAM Only definitions
|
||||
* --------------------
|
||||
*/
|
||||
|
||||
// For SAM3X:
|
||||
#define _useTimer1
|
||||
#define _useTimer2
|
||||
#define _useTimer3
|
||||
#define _useTimer4
|
||||
#define _useTimer5
|
||||
|
||||
/*
|
||||
TC0, chan 0 => TC0_Handler
|
||||
TC0, chan 1 => TC1_Handler
|
||||
TC0, chan 2 => TC2_Handler
|
||||
TC1, chan 0 => TC3_Handler
|
||||
TC1, chan 1 => TC4_Handler
|
||||
TC1, chan 2 => TC5_Handler
|
||||
TC2, chan 0 => TC6_Handler
|
||||
TC2, chan 1 => TC7_Handler
|
||||
TC2, chan 2 => TC8_Handler
|
||||
*/
|
||||
|
||||
#if defined (_useTimer1)
|
||||
#define TC_FOR_TIMER1 TC1
|
||||
#define CHANNEL_FOR_TIMER1 0
|
||||
#define ID_TC_FOR_TIMER1 ID_TC3
|
||||
#define IRQn_FOR_TIMER1 TC3_IRQn
|
||||
#define HANDLER_FOR_TIMER1 TC3_Handler
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
#define TC_FOR_TIMER2 TC1
|
||||
#define CHANNEL_FOR_TIMER2 1
|
||||
#define ID_TC_FOR_TIMER2 ID_TC4
|
||||
#define IRQn_FOR_TIMER2 TC4_IRQn
|
||||
#define HANDLER_FOR_TIMER2 TC4_Handler
|
||||
#endif
|
||||
#if defined (_useTimer3)
|
||||
#define TC_FOR_TIMER3 TC1
|
||||
#define CHANNEL_FOR_TIMER3 2
|
||||
#define ID_TC_FOR_TIMER3 ID_TC5
|
||||
#define IRQn_FOR_TIMER3 TC5_IRQn
|
||||
#define HANDLER_FOR_TIMER3 TC5_Handler
|
||||
#endif
|
||||
#if defined (_useTimer4)
|
||||
#define TC_FOR_TIMER4 TC0
|
||||
#define CHANNEL_FOR_TIMER4 2
|
||||
#define ID_TC_FOR_TIMER4 ID_TC2
|
||||
#define IRQn_FOR_TIMER4 TC2_IRQn
|
||||
#define HANDLER_FOR_TIMER4 TC2_Handler
|
||||
#endif
|
||||
#if defined (_useTimer5)
|
||||
#define TC_FOR_TIMER5 TC0
|
||||
#define CHANNEL_FOR_TIMER5 0
|
||||
#define ID_TC_FOR_TIMER5 ID_TC0
|
||||
#define IRQn_FOR_TIMER5 TC0_IRQn
|
||||
#define HANDLER_FOR_TIMER5 TC0_Handler
|
||||
#endif
|
||||
|
||||
typedef enum { _timer1, _timer2, _timer3, _timer4, _timer5, _Nbr_16timers } timer16_Sequence_t ;
|
||||
|
297
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/samd/Servo.cpp
Executable file
297
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/samd/Servo.cpp
Executable file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
Copyright (c) 2015 Arduino LLC. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAMD)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Servo.h>
|
||||
|
||||
#define usToTicks(_us) ((clockCyclesPerMicrosecond() * _us) / 16) // converts microseconds to tick
|
||||
#define ticksToUs(_ticks) (((unsigned) _ticks * 16) / clockCyclesPerMicrosecond()) // converts from ticks back to microseconds
|
||||
|
||||
#define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays
|
||||
|
||||
static servo_t servos[MAX_SERVOS]; // static array of servo structures
|
||||
|
||||
uint8_t ServoCount = 0; // the total number of attached servos
|
||||
|
||||
static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval)
|
||||
|
||||
// convenience macros
|
||||
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo
|
||||
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer
|
||||
#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel
|
||||
#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
|
||||
|
||||
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
|
||||
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
|
||||
|
||||
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY);
|
||||
|
||||
/************ static functions common to all instances ***********************/
|
||||
|
||||
void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel, uint8_t intFlag);
|
||||
#if defined (_useTimer1)
|
||||
void HANDLER_FOR_TIMER1(void) {
|
||||
Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, INTFLAG_BIT_FOR_TIMER_1);
|
||||
}
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
void HANDLER_FOR_TIMER2(void) {
|
||||
Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, INTFLAG_BIT_FOR_TIMER_2);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel, uint8_t intFlag)
|
||||
{
|
||||
if (currentServoIndex[timer] < 0) {
|
||||
tc->COUNT16.COUNT.reg = (uint16_t) 0;
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
} else {
|
||||
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) {
|
||||
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated
|
||||
}
|
||||
}
|
||||
|
||||
// Select the next servo controlled by this timer
|
||||
currentServoIndex[timer]++;
|
||||
|
||||
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) {
|
||||
if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated
|
||||
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
|
||||
}
|
||||
|
||||
// Get the counter value
|
||||
uint16_t tcCounterValue = tc->COUNT16.COUNT.reg;
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
|
||||
tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + SERVO(timer, currentServoIndex[timer]).ticks);
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
}
|
||||
else {
|
||||
// finished all channels so wait for the refresh period to expire before starting over
|
||||
|
||||
// Get the counter value
|
||||
uint16_t tcCounterValue = tc->COUNT16.COUNT.reg;
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
|
||||
if (tcCounterValue + 4UL < usToTicks(REFRESH_INTERVAL)) { // allow a few ticks to ensure the next OCR1A not missed
|
||||
tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(REFRESH_INTERVAL);
|
||||
}
|
||||
else {
|
||||
tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + 4UL); // at least REFRESH_INTERVAL has elapsed
|
||||
}
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
|
||||
currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
|
||||
}
|
||||
|
||||
// Clear the interrupt
|
||||
tc->COUNT16.INTFLAG.reg = intFlag;
|
||||
}
|
||||
|
||||
static inline void resetTC (Tc* TCx)
|
||||
{
|
||||
// Disable TCx
|
||||
TCx->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
|
||||
WAIT_TC16_REGS_SYNC(TCx)
|
||||
|
||||
// Reset TCx
|
||||
TCx->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
|
||||
WAIT_TC16_REGS_SYNC(TCx)
|
||||
while (TCx->COUNT16.CTRLA.bit.SWRST);
|
||||
}
|
||||
|
||||
static void _initISR(Tc *tc, uint8_t channel, uint32_t id, IRQn_Type irqn, uint8_t gcmForTimer, uint8_t intEnableBit)
|
||||
{
|
||||
// Enable GCLK for timer 1 (timer counter input clock)
|
||||
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(gcmForTimer));
|
||||
while (GCLK->STATUS.bit.SYNCBUSY);
|
||||
|
||||
// Reset the timer
|
||||
// TODO this is not the right thing to do if more than one channel per timer is used by the Servo library
|
||||
resetTC(tc);
|
||||
|
||||
// Set timer counter mode to 16 bits
|
||||
tc->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
|
||||
|
||||
// Set timer counter mode as normal PWM
|
||||
tc->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM;
|
||||
|
||||
// Set the prescaler factor to GCLK_TC/16. At nominal 48MHz GCLK_TC this is 3000 ticks per millisecond
|
||||
tc->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV16;
|
||||
|
||||
// Count up
|
||||
tc->COUNT16.CTRLBCLR.bit.DIR = 1;
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
|
||||
// First interrupt request after 1 ms
|
||||
tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(1000UL);
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
|
||||
// Configure interrupt request
|
||||
// TODO this should be changed if more than one channel per timer is used by the Servo library
|
||||
NVIC_DisableIRQ(irqn);
|
||||
NVIC_ClearPendingIRQ(irqn);
|
||||
NVIC_SetPriority(irqn, 0);
|
||||
NVIC_EnableIRQ(irqn);
|
||||
|
||||
// Enable the match channel interrupt request
|
||||
tc->COUNT16.INTENSET.reg = intEnableBit;
|
||||
|
||||
// Enable the timer and start it
|
||||
tc->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
|
||||
WAIT_TC16_REGS_SYNC(tc)
|
||||
}
|
||||
|
||||
static void initISR(timer16_Sequence_t timer)
|
||||
{
|
||||
#if defined (_useTimer1)
|
||||
if (timer == _timer1)
|
||||
_initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1, GCM_FOR_TIMER_1, INTENSET_BIT_FOR_TIMER_1);
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
if (timer == _timer2)
|
||||
_initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2, GCM_FOR_TIMER_2, INTENSET_BIT_FOR_TIMER_2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void finISR(timer16_Sequence_t timer)
|
||||
{
|
||||
#if defined (_useTimer1)
|
||||
// Disable the match channel interrupt request
|
||||
TC_FOR_TIMER1->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_1;
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
// Disable the match channel interrupt request
|
||||
TC_FOR_TIMER2->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_2;
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean isTimerActive(timer16_Sequence_t timer)
|
||||
{
|
||||
// returns true if any servo is active on this timer
|
||||
for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) {
|
||||
if(SERVO(timer,channel).Pin.isActive == true)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************** end of static functions ******************************/
|
||||
|
||||
Servo::Servo()
|
||||
{
|
||||
if (ServoCount < MAX_SERVOS) {
|
||||
this->servoIndex = ServoCount++; // assign a servo index to this instance
|
||||
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values
|
||||
} else {
|
||||
this->servoIndex = INVALID_SERVO; // too many servos
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Servo::attach(int pin)
|
||||
{
|
||||
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
|
||||
}
|
||||
|
||||
uint8_t Servo::attach(int pin, int min, int max)
|
||||
{
|
||||
timer16_Sequence_t timer;
|
||||
|
||||
if (this->servoIndex < MAX_SERVOS) {
|
||||
pinMode(pin, OUTPUT); // set servo pin to output
|
||||
servos[this->servoIndex].Pin.nbr = pin;
|
||||
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
|
||||
this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
|
||||
this->max = (MAX_PULSE_WIDTH - max)/4;
|
||||
// initialize the timer if it has not already been initialized
|
||||
timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||
if (isTimerActive(timer) == false) {
|
||||
initISR(timer);
|
||||
}
|
||||
servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
|
||||
}
|
||||
return this->servoIndex;
|
||||
}
|
||||
|
||||
void Servo::detach()
|
||||
{
|
||||
timer16_Sequence_t timer;
|
||||
|
||||
servos[this->servoIndex].Pin.isActive = false;
|
||||
timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||
if(isTimerActive(timer) == false) {
|
||||
finISR(timer);
|
||||
}
|
||||
}
|
||||
|
||||
void Servo::write(int value)
|
||||
{
|
||||
// treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
|
||||
if (value < MIN_PULSE_WIDTH)
|
||||
{
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
else if (value > 180)
|
||||
value = 180;
|
||||
|
||||
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
|
||||
}
|
||||
writeMicroseconds(value);
|
||||
}
|
||||
|
||||
void Servo::writeMicroseconds(int value)
|
||||
{
|
||||
// calculate and store the values for the given channel
|
||||
byte channel = this->servoIndex;
|
||||
if( (channel < MAX_SERVOS) ) // ensure channel is valid
|
||||
{
|
||||
if (value < SERVO_MIN()) // ensure pulse width is valid
|
||||
value = SERVO_MIN();
|
||||
else if (value > SERVO_MAX())
|
||||
value = SERVO_MAX();
|
||||
|
||||
value = value - TRIM_DURATION;
|
||||
value = usToTicks(value); // convert to ticks after compensating for interrupt overhead
|
||||
servos[channel].ticks = value;
|
||||
}
|
||||
}
|
||||
|
||||
int Servo::read() // return the value as degrees
|
||||
{
|
||||
return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180);
|
||||
}
|
||||
|
||||
int Servo::readMicroseconds()
|
||||
{
|
||||
unsigned int pulsewidth;
|
||||
if (this->servoIndex != INVALID_SERVO)
|
||||
pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION;
|
||||
else
|
||||
pulsewidth = 0;
|
||||
|
||||
return pulsewidth;
|
||||
}
|
||||
|
||||
bool Servo::attached()
|
||||
{
|
||||
return servos[this->servoIndex].Pin.isActive;
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ARCH_SAMD
|
71
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/samd/ServoTimers.h
Executable file
71
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo 2/src/samd/ServoTimers.h
Executable file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2015 Arduino LLC. All right reserved.
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines for 16 bit timers used with Servo library
|
||||
*
|
||||
* If _useTimerX is defined then TimerX is a 16 bit timer on the current board
|
||||
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
|
||||
* _Nbr_16timers indicates how many 16 bit timers are available.
|
||||
*/
|
||||
|
||||
#ifndef __SERVO_TIMERS_H__
|
||||
#define __SERVO_TIMERS_H__
|
||||
|
||||
/**
|
||||
* SAMD Only definitions
|
||||
* ---------------------
|
||||
*/
|
||||
|
||||
// For SAMD:
|
||||
#define _useTimer1
|
||||
//#define _useTimer2 // <- TODO do not activate until the code in Servo.cpp has been changed in order
|
||||
// to manage more than one channel per timer on the SAMD architecture
|
||||
|
||||
#if defined (_useTimer1)
|
||||
#define TC_FOR_TIMER1 TC4
|
||||
#define CHANNEL_FOR_TIMER1 0
|
||||
#define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0
|
||||
#define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0
|
||||
#define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0
|
||||
#define ID_TC_FOR_TIMER1 ID_TC4
|
||||
#define IRQn_FOR_TIMER1 TC4_IRQn
|
||||
#define HANDLER_FOR_TIMER1 TC4_Handler
|
||||
#define GCM_FOR_TIMER_1 GCM_TC4_TC5
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
#define TC_FOR_TIMER2 TC4
|
||||
#define CHANNEL_FOR_TIMER2 1
|
||||
#define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1
|
||||
#define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1
|
||||
#define ID_TC_FOR_TIMER2 ID_TC4
|
||||
#define IRQn_FOR_TIMER2 TC4_IRQn
|
||||
#define HANDLER_FOR_TIMER2 TC4_Handler
|
||||
#define GCM_FOR_TIMER_2 GCM_TC4_TC5
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
#if defined (_useTimer1)
|
||||
_timer1,
|
||||
#endif
|
||||
#if defined (_useTimer2)
|
||||
_timer2,
|
||||
#endif
|
||||
_Nbr_16timers } timer16_Sequence_t;
|
||||
|
||||
#endif // __SERVO_TIMERS_H__
|
BIN
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo.zip
Executable file
BIN
projects/elegoo-kit-lessons/Lesson 9 Servo/Servo.zip
Executable file
Binary file not shown.
27
projects/elegoo-kit-lessons/Lesson 9 Servo/servo/servo.ino
Normal file
27
projects/elegoo-kit-lessons/Lesson 9 Servo/servo/servo.ino
Normal file
@ -0,0 +1,27 @@
|
||||
//www.elegoo.com
|
||||
//2016.12.08
|
||||
#include </Users/Imogen/Documents/Arduino/libraries/Servo/Servo.h>
|
||||
#include </Users/Imogen/Documents/Arduino/libraries/Servo/Servo.cpp>
|
||||
|
||||
Servo myservo; // create servo object to control a servo
|
||||
// twelve servo objects can be created on most boards
|
||||
|
||||
int pos = 0; // variable to store the servo position
|
||||
|
||||
void setup() {
|
||||
myservo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (pos = 0; pos <= 90; pos += 1) { // goes from 0 degrees to 180 degrees
|
||||
// in steps of 1 degree
|
||||
myservo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
delay(50); // waits 15ms for the servo to reach the position
|
||||
}
|
||||
delay(1000);
|
||||
for (pos = 90; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
|
||||
myservo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
delay(50); // waits 15ms for the servo to reach the position
|
||||
}
|
||||
}
|
||||
|
14
projects/elegoo-kit-lessons/README.txt
Executable file
14
projects/elegoo-kit-lessons/README.txt
Executable file
@ -0,0 +1,14 @@
|
||||
Dear Customer,
|
||||
|
||||
Thanks a lot for your support and purchasing Elegoo products.
|
||||
|
||||
We keep updating our tutorialso the tutorial in the CD may not be the latest version.
|
||||
|
||||
If you need the latest tutorial, you may download the tutorial from www.elegoo.com
|
||||
|
||||
We apologize for the inconvenience caused and should you have additional questions or problems during testing,
|
||||
please feel free to contact us at service@elegoo.com or euservice@elegoo.com.
|
||||
|
||||
Thanks and best regards
|
||||
|
||||
Elegoo Support Team
|
BIN
projects/elegoo-kit-lessons/UNO R3 DRIVER FAQ.pdf
Executable file
BIN
projects/elegoo-kit-lessons/UNO R3 DRIVER FAQ.pdf
Executable file
Binary file not shown.
83
projects/i2c_scanner/i2c_scanner.ino
Normal file
83
projects/i2c_scanner/i2c_scanner.ino
Normal file
@ -0,0 +1,83 @@
|
||||
// --------------------------------------
|
||||
// i2c_scanner
|
||||
//
|
||||
// Version 1
|
||||
// This program (or code that looks like it)
|
||||
// can be found in many places.
|
||||
// For example on the Arduino.cc forum.
|
||||
// The original author is not know.
|
||||
// Version 2, Juni 2012, Using Arduino 1.0.1
|
||||
// Adapted to be as simple as possible by Arduino.cc user Krodal
|
||||
// Version 3, Feb 26 2013
|
||||
// V3 by louarnold
|
||||
// Version 4, March 3, 2013, Using Arduino 1.0.3
|
||||
// by Arduino.cc user Krodal.
|
||||
// Changes by louarnold removed.
|
||||
// Scanning addresses changed from 0...127 to 1...119,
|
||||
// according to the i2c scanner by Nick Gammon
|
||||
// http://www.gammon.com.au/forum/?id=10896
|
||||
// Version 5, March 28, 2013
|
||||
// As version 4, but address scans now to 127.
|
||||
// A sensor seems to use address 120.
|
||||
// Version 6, November 27, 2015.
|
||||
// Added waiting for the Leonardo serial communication.
|
||||
//
|
||||
//
|
||||
// This sketch tests the standard 7-bit addresses
|
||||
// Devices with higher bit address might not be seen properly.
|
||||
//
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Wire.begin();
|
||||
|
||||
Serial.begin(9600);
|
||||
while (!Serial); // Leonardo: wait for serial monitor
|
||||
Serial.println("\nI2C Scanner");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
byte error, address;
|
||||
int nDevices;
|
||||
|
||||
Serial.println("Scanning...");
|
||||
|
||||
nDevices = 0;
|
||||
for(address = 1; address < 127; address++ )
|
||||
{
|
||||
// The i2c_scanner uses the return value of
|
||||
// the Write.endTransmisstion to see if
|
||||
// a device did acknowledge to the address.
|
||||
Wire.beginTransmission(address);
|
||||
error = Wire.endTransmission();
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
Serial.print("I2C device found at address 0x");
|
||||
if (address<16)
|
||||
Serial.print("0");
|
||||
Serial.print(address,HEX);
|
||||
Serial.println(" !");
|
||||
|
||||
nDevices++;
|
||||
}
|
||||
else if (error==4)
|
||||
{
|
||||
Serial.print("Unknown error at address 0x");
|
||||
if (address<16)
|
||||
Serial.print("0");
|
||||
Serial.println(address,HEX);
|
||||
}
|
||||
}
|
||||
if (nDevices == 0)
|
||||
Serial.println("No I2C devices found\n");
|
||||
else
|
||||
Serial.println("done\n");
|
||||
|
||||
delay(5000); // wait 5 seconds for next scan
|
||||
}
|
43
projects/randomart_tester/randomart_tester.ino
Normal file
43
projects/randomart_tester/randomart_tester.ino
Normal file
@ -0,0 +1,43 @@
|
||||
int rPin = 11;
|
||||
int gPin = 10;
|
||||
int bPin = 9;
|
||||
|
||||
int tstPin = 3;
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
pinMode(rPin, OUTPUT); // R
|
||||
pinMode(gPin, OUTPUT); // G
|
||||
pinMode(bPin, OUTPUT); // B
|
||||
pinMode(5, OUTPUT); // transistor
|
||||
pinMode(4, OUTPUT); // transistor
|
||||
|
||||
pinMode(tstPin, OUTPUT); // test
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
if(rand()%2){
|
||||
digitalWrite(tstPin,HIGH);
|
||||
}
|
||||
else{
|
||||
digitalWrite(tstPin,LOW);
|
||||
}
|
||||
digitalWrite(rPin,0.6*15);
|
||||
digitalWrite(gPin,0.3*15*0);
|
||||
digitalWrite(bPin,0.1*15*0);
|
||||
if(rand()%2){
|
||||
digitalWrite(4,HIGH);
|
||||
}
|
||||
else{
|
||||
digitalWrite(4,LOW);
|
||||
}
|
||||
if(rand()%2){
|
||||
digitalWrite(5,HIGH);
|
||||
}
|
||||
else{
|
||||
digitalWrite(5,LOW);
|
||||
}
|
||||
// digitalWrite(5,LOW);
|
||||
delay(1000);
|
||||
}
|
BIN
projects/rfid/.DS_Store
vendored
Normal file
BIN
projects/rfid/.DS_Store
vendored
Normal file
Binary file not shown.
10
projects/rfid/.github/CONTRIBUTING.md
vendored
Normal file
10
projects/rfid/.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
Code style
|
||||
----------
|
||||
|
||||
1. Please use ``fixed integers``, see `stdint.h`_. Why? This library is compatible to different boards which use different architectures (16bit vs 32bit). So unfixed ``int`` has different sizes on different environments and may cause unpredictable behaviour.
|
||||
|
||||
2. If possible: use advantages of `c++11`, e.g. `constexpr`.
|
||||
|
||||
3. Use tab in source files. Space in examples.
|
||||
|
||||
4. Add documentation to **every** new function or parameter. Add documentation to most steps in your source code.
|
45
projects/rfid/.github/ISSUE_TEMPLATE.md
vendored
Normal file
45
projects/rfid/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<!-- BEGIN - This is a comment just for you visible
|
||||
|
||||
### Step 0: Are you in the right place?
|
||||
GitHub issues only for **bugs** or **improvements** of the library. All other topics, e.g. hardware/programming, will be closed.
|
||||
|
||||
For general support from the community, see [Arduino Forum](https://forum.arduino.cc/) or [StackOverflow](https://stackoverflow.com/questions/tagged/mifare).
|
||||
|
||||
Please use the following template to give us as mutch information as you can.
|
||||
|
||||
END - This is a comment just for you visible -->
|
||||
|
||||
### Step 1: Describe your environment
|
||||
|
||||
* OS version: _____
|
||||
* Arduino IDE version: _____
|
||||
* MFRC522 Library version: _____ <!-- comment: important! v1.x.x or master-branch? -->
|
||||
* Arduino device: _____
|
||||
* MFRC522 device: _____
|
||||
|
||||
### Step 2: Describe the problem
|
||||
|
||||
#### Affected file(s) or example(s):
|
||||
|
||||
* Filename 1
|
||||
* Filename 2
|
||||
|
||||
#### Steps to reproduce:
|
||||
|
||||
1. _____
|
||||
2. _____
|
||||
3. _____
|
||||
|
||||
#### Observed Results:
|
||||
|
||||
* What happened? This could be a description, log output, screenshot, etc.
|
||||
|
||||
#### Expected Results:
|
||||
|
||||
* What did you expect to happen?
|
||||
|
||||
#### Relevant Code:
|
||||
|
||||
```arduino
|
||||
// TODO(you): code here to reproduce the problem
|
||||
```
|
15
projects/rfid/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
15
projects/rfid/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<!-- BEGIN - This is a comment just for you visible
|
||||
|
||||
Please use the following template to give us as mutch information as you can.
|
||||
Not used rows can be deleted.
|
||||
|
||||
END - This is a comment just for you visible -->
|
||||
|
||||
| Q | A
|
||||
| ------------- | ---
|
||||
| Bug fix? | yes/no
|
||||
| New feature? | yes/no
|
||||
| Doc update? | yes/no
|
||||
| BC breaks? | yes/no <!-- BC = backwards compatibility -->
|
||||
| Deprecations? | yes/no
|
||||
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
|
6
projects/rfid/.gitignore
vendored
Normal file
6
projects/rfid/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
MFRC522.zip
|
||||
|
||||
# ignore IDE files
|
||||
.idea
|
||||
cmake
|
||||
CMakeLists.txt
|
40
projects/rfid/.travis.yml
Normal file
40
projects/rfid/.travis.yml
Normal file
@ -0,0 +1,40 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
|
||||
# Cache PlatformIO packages using Travis CI container-based infrastructure
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
|
||||
env:
|
||||
# add examples here and define which boards should be tested (only compile test)
|
||||
- PLATFORMIO_CI_SRC=examples/ChangeUID/ChangeUID.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/DumpInfo/DumpInfo.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/firmware_check/firmware_check.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/FixBrickedUID/FixBrickedUID.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/MifareClassicValueBlock/MifareClassicValueBlock.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/MinimalInterrupt/MinimalInterrupt.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/ReadAndWrite/ReadAndWrite.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/ReadUidMultiReader/ReadUidMultiReader.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/rfid_default_keys/rfid_default_keys.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/rfid_write_personal_data/rfid_write_personal_data.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/Ntag216_AUTH/Ntag216_AUTH.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/ReadNUID/ReadNUID.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/AccessControl/AccessControl.ino TESTBOARD=arduino_avr,teensy
|
||||
- PLATFORMIO_CI_SRC=examples/RFID-Cloner/RFID-Cloner.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
- PLATFORMIO_CI_SRC=examples/rfid_read_personal_data/rfid_read_personal_data.ino TESTBOARD=arduino_avr,arduino_arm,teensy,esp
|
||||
|
||||
install:
|
||||
- pip install -U platformio
|
||||
|
||||
script:
|
||||
# short the string comparison
|
||||
- stringContain() { [ -z "${2##*$1*}" ]; }
|
||||
# selectable board tests @Rotzbua
|
||||
# prints only warnings and errors, to show all remove "1>/dev/null"
|
||||
- board="arduino_avr"; if stringContain "$board" "$TESTBOARD"; then echo "check board $board"; ouput=$(platformio ci --lib=. --board=uno --board=megaatmega1280); echo "--<Result>--"; echo "$ouput" | grep -E "^(Device|Data|Program|text|[0-9])"; else echo "skip board test of $board"; fi
|
||||
- board="arduino_arm"; if stringContain "$board" "$TESTBOARD"; then echo "check board $board"; ouput=$(platformio ci --lib=. --board=due --board=zero); echo "--<Result>--"; echo "$ouput" | grep -E "^(Device|Data|Program|text|[0-9])"; else echo "skip board test of $board"; fi
|
||||
- board="teensy"; if stringContain "$board" "$TESTBOARD"; then echo "check board $board"; ouput=$(platformio ci --lib=. --board=teensy20 --board=teensy31); echo "--<Result>--"; echo "$ouput" | grep -E "^(Device|Data|Program|text|[0-9])"; else echo "skip board test of $board"; fi
|
||||
- board="esp"; if stringContain "$board" "$TESTBOARD"; then echo "check board $board"; ouput=$(platformio ci --lib=. --board=d1_mini); echo "--<Result>--"; echo "$ouput" | grep -E "^(Device|Data|Program|text|[0-9])"; else echo "skip board test of $board"; fi
|
314
projects/rfid/README.rst
Normal file
314
projects/rfid/README.rst
Normal file
@ -0,0 +1,314 @@
|
||||
MFRC522
|
||||
=======
|
||||
|
||||
.. image:: https://travis-ci.org/miguelbalboa/rfid.svg?branch=master
|
||||
:target: https://travis-ci.org/miguelbalboa/rfid
|
||||
.. image:: https://img.shields.io/badge/C%2B%2B-11-brightgreen.svg
|
||||
:target: `compatible ide`_
|
||||
.. image:: https://img.shields.io/github/release/miguelbalboa/rfid.svg?colorB=green
|
||||
:target: https://github.com/miguelbalboa/rfid/releases
|
||||
.. image:: https://img.shields.io/badge/ArduinoIDE-%3E%3D1.6.10-lightgrey.svg
|
||||
:target: `compatible ide`_
|
||||
|
||||
Arduino library for MFRC522 and other RFID RC522 based modules.
|
||||
|
||||
Read and write different types of Radio-Frequency IDentification (RFID) cards
|
||||
on your Arduino using a RC522 based reader connected via the Serial Peripheral
|
||||
Interface (SPI) interface.
|
||||
|
||||
|
||||
.. _development:
|
||||
Development
|
||||
----------
|
||||
**The development by owner miguelbalboa has ended**. Further development will be done by community. This library is still maintained by miguelbalboa, so make pull request if you like some new features or fixes. Support/issues should be solved by community.
|
||||
|
||||
|
||||
.. _what works and not:
|
||||
What works and not?
|
||||
----------
|
||||
|
||||
* **Works**
|
||||
|
||||
#. Communication (Crypto1) with MIFARE Classic (1k, 4k, Mini).
|
||||
#. Communication (Crypto1) with MIFARE Classic compatible PICCs.
|
||||
#. Firmware self check of MFRC522.
|
||||
#. Set the UID, write to sector 0, and unbrick Chinese UID changeable MIFARE cards.
|
||||
|
||||
* **Works partially**
|
||||
|
||||
#. Communication with MIFARE Ultralight.
|
||||
#. Other PICCs (Ntag216).
|
||||
#. More than 2 modules, require a multiplexer `#191 <https://github.com/miguelbalboa/rfid/issues/191#issuecomment-242631153>`_.
|
||||
|
||||
* **Doesn't work**
|
||||
|
||||
#. MIFARE DESFire, MIFARE DESFire EV1/EV2, not supported by software.
|
||||
#. Communication with 3DES or AES, not supported by software.
|
||||
#. Peer-to-peer (ISO/IEC 18092), not `supported by hardware`_.
|
||||
#. Communication with smart phone, not `supported by hardware`_.
|
||||
#. Card emulation, not `supported by hardware`_.
|
||||
#. Use of IRQ pin. But there is a proof-of-concept example.
|
||||
#. With Arduino Yun see `#111 <https://github.com/miguelbalboa/rfid/issues/111>`_, not supported by software.
|
||||
#. With Intel Galileo (Gen2) see `#310 <https://github.com/miguelbalboa/rfid/issues/310>`__, not supported by software.
|
||||
#. Power reduction modes `#269 <https://github.com/miguelbalboa/rfid/issues/269>`_, not supported by software.
|
||||
#. I2C instead of SPI `#240 <https://github.com/miguelbalboa/rfid/issues/240>`_, not supported by software.
|
||||
#. UART instead of SPI `#281 <https://github.com/miguelbalboa/rfid/issues/281>`_, not supported by software.
|
||||
|
||||
* **Need more?**
|
||||
|
||||
#. If software: code it and make a pull request.
|
||||
#. If hardware: buy a more expensive like PN532 (supports NFC and many more, but costs about $15).
|
||||
|
||||
|
||||
.. _compatible ide:
|
||||
Compatible IDE
|
||||
----------
|
||||
This library works with Arduino IDE 1.6, older versions are **not supported** and will cause compiler errors. The built-in library manager is supported.
|
||||
|
||||
If you use your own compiler, you have to enable ``c++11``-support.
|
||||
|
||||
|
||||
.. _compatible boards:
|
||||
Compatible boards
|
||||
----------
|
||||
|
||||
**!!!Only for advanced users!!!**
|
||||
|
||||
This library is compatible with the Teensy and ESP8266 if you use the board plugin of the Arduino IDE. Not all examples are available for every board. You also have to change pins. See `pin layout`_.
|
||||
|
||||
Some user made some patches/suggestions/ports for other boards:
|
||||
|
||||
* Linux: https://github.com/miguelbalboa/rfid/pull/216
|
||||
* chipKIT: https://github.com/miguelbalboa/rfid/pull/230
|
||||
* ESP8266 (native): https://github.com/miguelbalboa/rfid/pull/235
|
||||
* ESP8266 nonos sdk: https://github.com/mmmmar/esp8266-mfrc522
|
||||
* LPCOPen (in C): https://github.com/miguelbalboa/rfid/pull/258
|
||||
|
||||
Note that the main target/support of library is still Arduino.
|
||||
|
||||
.. _support issue:
|
||||
Support/issue
|
||||
----------
|
||||
1. First checkout `what works and not`_ and `troubleshooting`_ .
|
||||
|
||||
2. It seems to be a hardware issue or you need support to program your project?
|
||||
Please ask in the official `Arduino forum`_, where you would get a much faster answer than on github.
|
||||
|
||||
3. It seems to be a software issue?
|
||||
Open an issue on github.
|
||||
|
||||
|
||||
.. _code style:
|
||||
Code style
|
||||
----------
|
||||
|
||||
Please use ``fixed integers``, see `stdint.h`_. Why? This library is compatible with different boards which use different architectures (16bit and 32bit.) Unfixed ``int`` variables have different sizes in different environments and may cause unpredictable behaviour.
|
||||
|
||||
|
||||
.. _pin layout:
|
||||
Pin Layout
|
||||
----------
|
||||
|
||||
The following table shows the typical pin layout used:
|
||||
|
||||
+-----------+----------+---------------------------------------------------------------+--------------------------+
|
||||
| | PCD | Arduino | Teensy |
|
||||
| +----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
| | MFRC522 | Uno / 101 | Mega | Nano v3 |Leonardo / Micro | Pro Micro | 2.0 | ++ 2.0 | 3.1 |
|
||||
+-----------+----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
| Signal | Pin | Pin | Pin | Pin | Pin | Pin | Pin | Pin | Pin |
|
||||
+===========+==========+=============+=========+=========+=================+===========+========+========+========+
|
||||
| RST/Reset | RST | 9 [1]_ | 5 [1]_ | D9 | RESET / ICSP-5 | RST | 7 | 4 | 9 |
|
||||
+-----------+----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
| SPI SS | SDA [3]_ | 10 [2]_ | 53 [2]_ | D10 | 10 | 10 | 0 | 20 | 10 |
|
||||
+-----------+----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
| SPI MOSI | MOSI | 11 / ICSP-4 | 51 | D11 | ICSP-4 | 16 | 2 | 22 | 11 |
|
||||
+-----------+----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
| SPI MISO | MISO | 12 / ICSP-1 | 50 | D12 | ICSP-1 | 14 | 3 | 23 | 12 |
|
||||
+-----------+----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
| SPI SCK | SCK | 13 / ICSP-3 | 52 | D13 | ICSP-3 | 15 | 1 | 21 | 13 |
|
||||
+-----------+----------+-------------+---------+---------+-----------------+-----------+--------+--------+--------+
|
||||
|
||||
+-----------+---------------+
|
||||
| | ESP8266 |
|
||||
| +---------------+
|
||||
| | Wemos D1 mini |
|
||||
+-----------+---------------+
|
||||
| Signal | Pin |
|
||||
+===========+===============+
|
||||
| RST/Reset | D3 |
|
||||
+-----------+---------------+
|
||||
| SPI SS | D8 |
|
||||
+-----------+---------------+
|
||||
| SPI MOSI | D7 |
|
||||
+-----------+---------------+
|
||||
| SPI MISO | D6 |
|
||||
+-----------+---------------+
|
||||
| SPI SCK | D5 |
|
||||
+-----------+---------------+
|
||||
|
||||
.. [1] Configurable, typically defined as RST_PIN in sketch/program.
|
||||
.. [2] Configurable, typically defined as SS_PIN in sketch/program.
|
||||
.. [3] The SDA pin might be labeled SS on some/older MFRC522 boards.
|
||||
|
||||
|
||||
.. _hardware:
|
||||
Hardware
|
||||
--------
|
||||
|
||||
There are three hardware components involved:
|
||||
|
||||
1. **Micro Controller**:
|
||||
|
||||
* An `Arduino`_ or compatible executing the Sketch using this library.
|
||||
|
||||
* Prices vary from USD 7 for clones, to USD 75 for "starter kits" (which
|
||||
might be a good choice if this is your first exposure to Arduino;
|
||||
check if such kit already includes the Arduino, Reader, and some Tags).
|
||||
|
||||
2. **Proximity Coupling Device (PCD)**:
|
||||
|
||||
* The PCD is the actual RFID **Reader** based on the `NXP MFRC522`_ Contactless
|
||||
Reader Integrated Circuit.
|
||||
|
||||
* Readers can be found on `eBay`_ for around USD 5: search for *"rc522"*.
|
||||
|
||||
* You can also find them on several web stores. They are often included in
|
||||
*"starter kits"*, so check your favourite electronics provider as well.
|
||||
|
||||
3. **Proximity Integrated Circuit Card (PICC)**:
|
||||
|
||||
* The PICC is the RFID **Card** or **Tag** using the `ISO/IEC 14443A`_
|
||||
interface, for example Mifare or NTAG203.
|
||||
|
||||
* One or two might be included with the Reader or *"starter kit"* already.
|
||||
|
||||
|
||||
.. _protocol:
|
||||
Protocols
|
||||
---------
|
||||
|
||||
1. The micro controller and the reader use SPI for communication.
|
||||
|
||||
* The protocol is described in the `NXP MFRC522`_ datasheet.
|
||||
|
||||
* See the `Pin Layout`_ section for details on connecting the pins.
|
||||
|
||||
2. The reader and the tags communicate using a 13.56 MHz electromagnetic field.
|
||||
|
||||
* The protocol is defined in ISO/IEC 14443-3:2011 Part 3 Type A.
|
||||
|
||||
* Details are found in chapter 6 *"Type A – Initialization and anticollision"*.
|
||||
|
||||
* See http://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf for a free version
|
||||
of the final draft (which might be outdated in some areas).
|
||||
|
||||
* The reader does not support ISO/IEC 14443-3 Type B.
|
||||
|
||||
|
||||
.. _security:
|
||||
Security
|
||||
-------
|
||||
This library only supports crypto1-encrypted communication. Crypto1 has been known as `broken`_ for a few years, so it does NOT offer ANY security, it is virtually unencrypted communication. **Do not use it for any security related applications!**
|
||||
|
||||
This library does not offer 3DES or AES authentication used by cards like the Mifare DESFire, it may be possible to be implemented because the datasheet says there is support. We hope for pull requests :).
|
||||
|
||||
|
||||
.. _troubleshooting:
|
||||
Troubleshooting
|
||||
-------
|
||||
|
||||
* **I don't get input from reader** or **WARNING: Communication failure, is the MFRC522 properly connected?**
|
||||
|
||||
#. Check your connection, see `Pin Layout`_ .
|
||||
#. Check voltage. Most breakouts work with 3.3V.
|
||||
#. SPI only works with 3.3V, most breakouts seem 5V tollerant, but try a level shifter.
|
||||
#. SPI does not like long connections. Try shorter connections.
|
||||
#. SPI does not like prototyping boards. Try soldered connections.
|
||||
#. According to reports #101, #126 and #131, there may be a problem with the soldering on the MFRC522 breakout. You could fix this on your own.
|
||||
|
||||
|
||||
* **Sometimes I get timeouts** or **sometimes tag/card does not work.**
|
||||
|
||||
#. Try the other side of the antenna.
|
||||
#. Try to decrease the distance between the MFRC522 and your tag.
|
||||
#. Increase the antenna gain per firmware: ``mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);``
|
||||
#. Use better power supply.
|
||||
#. Hardware may be corrupted, most products are from china and sometimes the quality is really poor. Contact your seller.
|
||||
|
||||
|
||||
* **My tag/card doesn't work.**
|
||||
|
||||
#. Distance between antenna and token too large (>1cm).
|
||||
#. You got the wrong type PICC. Is it really 13.56 MHz? Is it really a Mifare Type A?
|
||||
#. NFC tokens are not supported. Some may work.
|
||||
#. Animal RFID tags are not supported. They use a different frequency (125 kHz).
|
||||
#. Hardware may be corrupted, most products are from china and sometimes the quality is really poor. Contact your seller.
|
||||
#. Newer versions of Mifare cards like DESFire/Ultralight maybe not work according to missing authentification, see `security`_ or different `protocol`_.
|
||||
#. Some boards bought from chinese manufactures do not use the best components and this can affect the detection of different types of tag/card. In some of these boards, the L1 and L2 inductors do not have a high enough current so the signal generated is not enough to get Ultralight C and NTAG203 tags to work, replacing those with same inductance (2.2uH) but higher operating current inductors should make things work smoothly. Also, in some of those boards the harmonic and matching circuit needs to be tuned, for this replace C4 and C5 with 33pf capacitors and you are all set. (Source: `Mikro Elektronika`_)
|
||||
|
||||
* **My mobile phone doesn't recognize the MFRC522** or **my MFRC522 can't read data from other MFRC522**
|
||||
|
||||
#. Card simmulation is not supported.
|
||||
#. Communication with mobile phones is not supported.
|
||||
#. Peer to peer communication is not supported.
|
||||
|
||||
|
||||
* **I need more features.**
|
||||
|
||||
#. If software: code it and make a pull request.
|
||||
#. If hardware: buy a more expensive chip like the PN532 (supports NFC and many more, but costs about $15)
|
||||
|
||||
|
||||
.. _license:
|
||||
License
|
||||
-------
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to https://unlicense.org/
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
The MFRC522 library was first created in Jan 2012 by Miguel Balboa (from
|
||||
http://circuitito.com) based on code by Dr. Leong (from http://B2CQSHOP.com)
|
||||
for *"Arduino RFID module Kit 13.56 Mhz with Tags SPI W and R By COOQRobot"*.
|
||||
|
||||
It was translated into English and rewritten/refactored in the fall of 2013
|
||||
by Søren Thing Andersen (from http://access.thing.dk).
|
||||
|
||||
It has been extended with functionality to alter sector 0 on Chinese UID changeable MIFARE card in Oct 2014 by Tom Clement (from http://tomclement.nl).
|
||||
|
||||
|
||||
.. _arduino: https://arduino.cc/
|
||||
.. _ebay: https://www.ebay.com/
|
||||
.. _iso/iec 14443a: https://en.wikipedia.org/wiki/ISO/IEC_14443
|
||||
.. _iso/iec 14443-3\:2011 part 3:
|
||||
.. _nxp mfrc522: https://www.nxp.com/documents/data_sheet/MFRC522.pdf
|
||||
.. _broken: https://eprint.iacr.org/2008/166
|
||||
.. _supported by hardware: https://web.archive.org/web/20151210045625/http://www.nxp.com/documents/leaflet/939775017564.pdf
|
||||
.. _Arduino forum: https://forum.arduino.cc
|
||||
.. _stdint.h: https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdint.h
|
||||
.. _Mikro Elektronika: https://forum.mikroe.com/viewtopic.php?f=147&t=64203
|
24
projects/rfid/UNLICENSE
Normal file
24
projects/rfid/UNLICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
150
projects/rfid/changes.txt
Normal file
150
projects/rfid/changes.txt
Normal file
@ -0,0 +1,150 @@
|
||||
-- Add changes to unreleased tag until we make a release.
|
||||
|
||||
unreleased
|
||||
-
|
||||
|
||||
unreleased, v1.4.0
|
||||
- Removed: void PCD_Init(byte resetPowerDownPin);
|
||||
- Removed: MFRC522(byte resetPowerDownPin);
|
||||
- Changed default initialisation of SS pin with constants of arduino.h are not done anymore
|
||||
- Replaced UINT8_MAX by UNUSED_PIN
|
||||
- Replaced default value NULL for pointer with correct nullptr
|
||||
- Added pin layout for wemos d1 mini @mmone
|
||||
- Added alternative fritzing layout for mfrc522 reader @jose1711
|
||||
- Added soft power control functions @Bill2462
|
||||
- Fixed typo in example ReadAndWrite.ino @Drachenfrucht1
|
||||
- Fixed grammar @KiddieD
|
||||
- Fixed infinite loop in example AccessControl.ino @mads256c
|
||||
|
||||
22 Mar 2017, v1.3.6
|
||||
- Added deprecate and compiler warnings @Rotzbua
|
||||
|
||||
8 Apr 2017, v1.3.5
|
||||
- Updated "AccessControl.ino", bugs fixed and alterate Wipe button polling method without using other library @beyondszine reviewed by @omersiar
|
||||
- Updated README notice about port for esp8266 @mmmmar
|
||||
|
||||
7 Apr 2017, v1.3.4
|
||||
- Added new example "rfid_read_personal_data.ino" @ryand1011
|
||||
- Updated example "rfid_write_personal_data.ino" code style to Arduino IDE @Rotzbua
|
||||
- Removed (temp.) Teensy from travis build script because fails @Rotzbua
|
||||
|
||||
26 Mar 2017, v1.3.3
|
||||
- Fixed bugs in MFRC522Extended, now should work with Desfire.h from JPG-Consulting @Rotzbua
|
||||
- Fixed UINT8_MAX error @Rotzbua
|
||||
|
||||
15 Mar 2017, v1.3.2
|
||||
- Added ESP8266 to library.properties
|
||||
|
||||
15 Mar 2017, v1.3.1
|
||||
- Fixed compiler warning in MFRC522Extended @Rotzbua
|
||||
- Removed unused function @Rotzbua
|
||||
|
||||
13 Mar 2017, v1.3.0
|
||||
- Warning: Source has moved to folder src!
|
||||
- Added addtional class to support ISO/IEC 14443-4 PICCs @JPG-Consulting
|
||||
- Added RATS (Request for Answer To Select) @JPG-Consulting
|
||||
- More information see https://github.com/miguelbalboa/rfid/pull/271 @JPG-Consulting
|
||||
|
||||
13 Mar 2017, v1.2.1
|
||||
- Removed need for reset pin #275 @tkoester
|
||||
- Added SPI speed option + Various minor changes #276 @tuyethoa08041997
|
||||
- Updated documentation, travis build script and small code change @Rotzbua
|
||||
|
||||
3 Jan 2017, v1.2.0
|
||||
- Warning: This version introduce usage of stdint.h, usage of not well defined int types are abandoned.
|
||||
Interface has changed: e.g. long -> int32_t
|
||||
@Rotzbua
|
||||
- Removed problematic example examples/servo_motor/servo_motor.ino @omersiar
|
||||
- Added examples/AccessControl/AccessControl.ino @omersiar
|
||||
- Fixed minor issues reported in #211 @omersiar
|
||||
- Added bad components hint to README @danielcbit
|
||||
- Fixed selftest @surr
|
||||
- Fixed auth problem with long UIDs @surr
|
||||
|
||||
26 Aug 2016, v1.1.9
|
||||
- Warning: Only Arduino IDE version 1.6 is supported, please update your IDE to 1.6 to use this Library.
|
||||
- Added ESP8266 platform support @Rotzbua
|
||||
- Changed README.rst content to show more info @Rotzbua
|
||||
- Minor Changes to examples/ReadUidMultiReader/ReadUidMultiReader.ino example @Rotzbua
|
||||
|
||||
11 Feb 2016, v1.1.8
|
||||
- Added examples/MinimalInterrupt/MinimalInterrupt.ino example, Interrupt example @lmmeng
|
||||
- Added .gitignore file allows the project to be more easily used as a subproject. @BenWiederhake
|
||||
- Added Added Teensy 2.0 & Tensy++ 2.0 pinouts to README.rst @jkutianski
|
||||
|
||||
16 Jan 2016, v1.1.7
|
||||
- README.rst Spelling and Grammar Tweak @cuthbertnibbles
|
||||
- Added examples/servo_motor/servo_motor.ino example, Arduino RFID Access Control with a Servo Motor @techied
|
||||
- Added examples/RFID-Cloner/RFID-Cloner.ino Copy from rfid cards with standard authentication @stefanblommaert
|
||||
- Fix compile error at examples/RFID-Cloner/RFID-Cloner.ino, using MFRC522:::PICC_Type, @Rotzbua
|
||||
|
||||
06 Jan 2016, v1.1.6
|
||||
- Fixed compilation error for examples/ReadNUID/ReadNUID.ino example. @Rotzbua
|
||||
|
||||
04 Jan 2016, v1.1.5
|
||||
- Use settings functions on SPI libraries, setSPIConfig was deleted, now the library use SPI.beginTransaction() and SPI.endTransaction() @sophiekovalevsky
|
||||
- Added examples/ReadNUID/ReadNUID.ino example, showing how to read new NUID from a PICC to serial. @sophiekovalevsky
|
||||
|
||||
03 Jan 2016, v1.1.4
|
||||
- Added Authentication with Ntag 213,215,216 returns the pACK MFRC522::PCD_NTAG216_AUTH @Gargantuanman
|
||||
- Starting to use versions http://semver.org/
|
||||
- Continuous Integration @ivankravets
|
||||
- functions return MFRC522::StatusCode and MFRC522::PICC_Type instead of generic byte @rotzbua
|
||||
- removed int-values of MFRC522::StatusCode and MFRC522::PICC_Type @rotzbua
|
||||
|
||||
05 Dec 2015
|
||||
- recognize infineon cards correctly @mayatforest
|
||||
- added multi reader support, see example @lmmeng
|
||||
|
||||
10 Nov 2014
|
||||
- Updated the changelog.
|
||||
- Added makefile.
|
||||
|
||||
24 Oct 2014
|
||||
- Added PlatformIO-based manifest file.
|
||||
|
||||
17 Jul 2014
|
||||
- Written documentation for the library.
|
||||
- Added rfid_default_keys example.
|
||||
|
||||
11 Jun 2014
|
||||
- Updated example: ReadAndWrite.
|
||||
|
||||
14 Apr 2014
|
||||
- Updated examples: DumpInfo, MifareClassicValueBlock, and ReadAndWrite.
|
||||
|
||||
12 Feb 2014
|
||||
- Fixed resetPowerDownPin initial state.
|
||||
|
||||
29 Jan 2014
|
||||
- Fixed chipSelectPin initial state.
|
||||
|
||||
30 Nov 2013
|
||||
- Examples put in their own folders.
|
||||
- Updated the keywords.txt file.
|
||||
|
||||
12 Nov 2013
|
||||
- Updated examples: DumpInfo, MifareClassicValueBlock, and ReadAndWrite.
|
||||
|
||||
20 Oct 2013
|
||||
- All constants, functions and parameters are now commented in English.
|
||||
- Code refactored, most function names have changed.
|
||||
- Support ISO-14443-3 anti collission and 4/7/10 byte UIDs (cascade levels).
|
||||
- Added functions for MIFARE Classic Decrement/Increment/Restore/Transfer
|
||||
and MIFARE Ultralight Write.
|
||||
- New examples written.
|
||||
|
||||
19 Oct 2013
|
||||
- Renamed library from RFID to MFRC522 (RFID seemed to generic).
|
||||
- Register names changed to comply with datasheet.
|
||||
- Global defines moved into class.
|
||||
|
||||
24 Sep 2013
|
||||
- Turn off encryption when tag is halted.
|
||||
|
||||
27 Jan 2013
|
||||
- Added README and small TODO list.
|
||||
- Added example to show Serial on LCD display.
|
||||
|
||||
09 Sep 2012
|
||||
- Initial commit to GitHub.
|
BIN
projects/rfid/doc/fritzing/Arduino-Uno-r3-with-RFID-RC522.fzz
Normal file
BIN
projects/rfid/doc/fritzing/Arduino-Uno-r3-with-RFID-RC522.fzz
Normal file
Binary file not shown.
BIN
projects/rfid/doc/fritzing/Arduino-Uno-r3-with-RFID-RC522.png
Normal file
BIN
projects/rfid/doc/fritzing/Arduino-Uno-r3-with-RFID-RC522.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 282 KiB |
BIN
projects/rfid/doc/fritzing/RFID-RC522 - Pin Layout.png
Executable file
BIN
projects/rfid/doc/fritzing/RFID-RC522 - Pin Layout.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 162 KiB |
BIN
projects/rfid/doc/fritzing/RFID-RC522-v2.fzpz
Normal file
BIN
projects/rfid/doc/fritzing/RFID-RC522-v2.fzpz
Normal file
Binary file not shown.
BIN
projects/rfid/doc/fritzing/RFID-RC522-v2.png
Normal file
BIN
projects/rfid/doc/fritzing/RFID-RC522-v2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
projects/rfid/doc/fritzing/RFID-RC522-v3.fzpz
Normal file
BIN
projects/rfid/doc/fritzing/RFID-RC522-v3.fzpz
Normal file
Binary file not shown.
BIN
projects/rfid/doc/fritzing/RFID-RC522-v3.png
Normal file
BIN
projects/rfid/doc/fritzing/RFID-RC522-v3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
projects/rfid/doc/rfidmifare.doc
Normal file
BIN
projects/rfid/doc/rfidmifare.doc
Normal file
Binary file not shown.
BIN
projects/rfid/doc/rfidmifare.pdf
Normal file
BIN
projects/rfid/doc/rfidmifare.pdf
Normal file
Binary file not shown.
551
projects/rfid/examples/AccessControl/AccessControl.ino
Normal file
551
projects/rfid/examples/AccessControl/AccessControl.ino
Normal file
@ -0,0 +1,551 @@
|
||||
/*
|
||||
--------------------------------------------------------------------------------------------------------------------
|
||||
Example sketch/program showing An Arduino Door Access Control featuring RFID, EEPROM, Relay
|
||||
--------------------------------------------------------------------------------------------------------------------
|
||||
This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
|
||||
|
||||
This example showing a complete Door Access Control System
|
||||
|
||||
Simple Work Flow (not limited to) :
|
||||
+---------+
|
||||
+----------------------------------->READ TAGS+^------------------------------------------+
|
||||
| +--------------------+ |
|
||||
| | | |
|
||||
| | | |
|
||||
| +----v-----+ +-----v----+ |
|
||||
| |MASTER TAG| |OTHER TAGS| |
|
||||
| +--+-------+ ++-------------+ |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| +-----v---+ +----v----+ +----v------+ |
|
||||
| +------------+READ TAGS+---+ |KNOWN TAG| |UNKNOWN TAG| |
|
||||
| | +-+-------+ | +-----------+ +------------------+ |
|
||||
| | | | | | |
|
||||
| +----v-----+ +----v----+ +--v--------+ +-v----------+ +------v----+ |
|
||||
| |MASTER TAG| |KNOWN TAG| |UNKNOWN TAG| |GRANT ACCESS| |DENY ACCESS| |
|
||||
| +----------+ +---+-----+ +-----+-----+ +-----+------+ +-----+-----+ |
|
||||
| | | | | |
|
||||
| +----+ +----v------+ +--v---+ | +--------------->
|
||||
+-------+EXIT| |DELETE FROM| |ADD TO| | |
|
||||
+----+ | EEPROM | |EEPROM| | |
|
||||
+-----------+ +------+ +-------------------------------+
|
||||
|
||||
|
||||
Use a Master Card which is act as Programmer then you can able to choose card holders who will granted access or not
|
||||
|
||||
* **Easy User Interface**
|
||||
|
||||
Just one RFID tag needed whether Delete or Add Tags. You can choose to use Leds for output or Serial LCD module to inform users.
|
||||
|
||||
* **Stores Information on EEPROM**
|
||||
|
||||
Information stored on non volatile Arduino's EEPROM memory to preserve Users' tag and Master Card. No Information lost
|
||||
if power lost. EEPROM has unlimited Read cycle but roughly 100,000 limited Write cycle.
|
||||
|
||||
* **Security**
|
||||
To keep it simple we are going to use Tag's Unique IDs. It's simple and not hacker proof.
|
||||
|
||||
@license Released into the public domain.
|
||||
|
||||
Typical pin layout used:
|
||||
-----------------------------------------------------------------------------------------
|
||||
MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
Signal Pin Pin Pin Pin Pin Pin
|
||||
-----------------------------------------------------------------------------------------
|
||||
RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
|
||||
SPI SS SDA(SS) 10 53 D10 10 10
|
||||
SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*/
|
||||
|
||||
#include <EEPROM.h> // We are going to read and write PICC's UIDs from/to EEPROM
|
||||
#include <SPI.h> // RC522 Module uses SPI protocol
|
||||
#include <MFRC522.h> // Library for Mifare RC522 Devices
|
||||
|
||||
/*
|
||||
Instead of a Relay you may want to use a servo. Servos can lock and unlock door locks too
|
||||
Relay will be used by default
|
||||
*/
|
||||
|
||||
// #include <Servo.h>
|
||||
|
||||
/*
|
||||
For visualizing whats going on hardware we need some leds and to control door lock a relay and a wipe button
|
||||
(or some other hardware) Used common anode led,digitalWriting HIGH turns OFF led Mind that if you are going
|
||||
to use common cathode led or just seperate leds, simply comment out #define COMMON_ANODE,
|
||||
*/
|
||||
|
||||
#define COMMON_ANODE
|
||||
|
||||
#ifdef COMMON_ANODE
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#else
|
||||
#define LED_ON HIGH
|
||||
#define LED_OFF LOW
|
||||
#endif
|
||||
|
||||
constexpr uint8_t redLed = 7; // Set Led Pins
|
||||
constexpr uint8_t greenLed = 6;
|
||||
constexpr uint8_t blueLed = 5;
|
||||
|
||||
constexpr uint8_t relay = 4; // Set Relay Pin
|
||||
constexpr uint8_t wipeB = 3; // Button pin for WipeMode
|
||||
|
||||
boolean match = false; // initialize card match to false
|
||||
boolean programMode = false; // initialize programming mode to false
|
||||
boolean replaceMaster = false;
|
||||
|
||||
uint8_t successRead; // Variable integer to keep if we have Successful Read from Reader
|
||||
|
||||
byte storedCard[4]; // Stores an ID read from EEPROM
|
||||
byte readCard[4]; // Stores scanned ID read from RFID Module
|
||||
byte masterCard[4]; // Stores master card's ID read from EEPROM
|
||||
|
||||
// Create MFRC522 instance.
|
||||
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
|
||||
constexpr uint8_t SS_PIN = 10; // Configurable, see typical pin layout above
|
||||
|
||||
MFRC522 mfrc522(SS_PIN, RST_PIN);
|
||||
|
||||
///////////////////////////////////////// Setup ///////////////////////////////////
|
||||
void setup() {
|
||||
//Arduino Pin Configuration
|
||||
pinMode(redLed, OUTPUT);
|
||||
pinMode(greenLed, OUTPUT);
|
||||
pinMode(blueLed, OUTPUT);
|
||||
pinMode(wipeB, INPUT_PULLUP); // Enable pin's pull up resistor
|
||||
pinMode(relay, OUTPUT);
|
||||
//Be careful how relay circuit behave on while resetting or power-cycling your Arduino
|
||||
digitalWrite(relay, HIGH); // Make sure door is locked
|
||||
digitalWrite(redLed, LED_OFF); // Make sure led is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure led is off
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure led is off
|
||||
|
||||
//Protocol Configuration
|
||||
Serial.begin(9600); // Initialize serial communications with PC
|
||||
SPI.begin(); // MFRC522 Hardware uses SPI protocol
|
||||
mfrc522.PCD_Init(); // Initialize MFRC522 Hardware
|
||||
|
||||
//If you set Antenna Gain to Max it will increase reading distance
|
||||
//mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
|
||||
|
||||
Serial.println(F("Access Control Example v0.1")); // For debugging purposes
|
||||
ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details
|
||||
|
||||
//Wipe Code - If the Button (wipeB) Pressed while setup run (powered on) it wipes EEPROM
|
||||
if (digitalRead(wipeB) == LOW) { // when button pressed pin should get low, button connected to ground
|
||||
digitalWrite(redLed, LED_ON); // Red Led stays on to inform user we are going to wipe
|
||||
Serial.println(F("Wipe Button Pressed"));
|
||||
Serial.println(F("You have 10 seconds to Cancel"));
|
||||
Serial.println(F("This will be remove all records and cannot be undone"));
|
||||
bool buttonState = monitorWipeButton(10000); // Give user enough time to cancel operation
|
||||
if (buttonState == true && digitalRead(wipeB) == LOW) { // If button still be pressed, wipe EEPROM
|
||||
Serial.println(F("Starting Wiping EEPROM"));
|
||||
for (uint16_t x = 0; x < EEPROM.length(); x = x + 1) { //Loop end of EEPROM address
|
||||
if (EEPROM.read(x) == 0) { //If EEPROM address 0
|
||||
// do nothing, already clear, go to the next address in order to save time and reduce writes to EEPROM
|
||||
}
|
||||
else {
|
||||
EEPROM.write(x, 0); // if not write 0 to clear, it takes 3.3mS
|
||||
}
|
||||
}
|
||||
Serial.println(F("EEPROM Successfully Wiped"));
|
||||
digitalWrite(redLed, LED_OFF); // visualize a successful wipe
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_ON);
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_OFF);
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_ON);
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_OFF);
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Wiping Cancelled")); // Show some feedback that the wipe button did not pressed for 15 seconds
|
||||
digitalWrite(redLed, LED_OFF);
|
||||
}
|
||||
}
|
||||
// Check if master card defined, if not let user choose a master card
|
||||
// This also useful to just redefine the Master Card
|
||||
// You can keep other EEPROM records just write other than 143 to EEPROM address 1
|
||||
// EEPROM address 1 should hold magical number which is '143'
|
||||
if (EEPROM.read(1) != 143) {
|
||||
Serial.println(F("No Master Card Defined"));
|
||||
Serial.println(F("Scan A PICC to Define as Master Card"));
|
||||
do {
|
||||
successRead = getID(); // sets successRead to 1 when we get read from reader otherwise 0
|
||||
digitalWrite(blueLed, LED_ON); // Visualize Master Card need to be defined
|
||||
delay(200);
|
||||
digitalWrite(blueLed, LED_OFF);
|
||||
delay(200);
|
||||
}
|
||||
while (!successRead); // Program will not go further while you not get a successful read
|
||||
for ( uint8_t j = 0; j < 4; j++ ) { // Loop 4 times
|
||||
EEPROM.write( 2 + j, readCard[j] ); // Write scanned PICC's UID to EEPROM, start from address 3
|
||||
}
|
||||
EEPROM.write(1, 143); // Write to EEPROM we defined Master Card.
|
||||
Serial.println(F("Master Card Defined"));
|
||||
}
|
||||
Serial.println(F("-------------------"));
|
||||
Serial.println(F("Master Card's UID"));
|
||||
for ( uint8_t i = 0; i < 4; i++ ) { // Read Master Card's UID from EEPROM
|
||||
masterCard[i] = EEPROM.read(2 + i); // Write it to masterCard
|
||||
Serial.print(masterCard[i], HEX);
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println(F("-------------------"));
|
||||
Serial.println(F("Everything is ready"));
|
||||
Serial.println(F("Waiting PICCs to be scanned"));
|
||||
cycleLeds(); // Everything ready lets give user some feedback by cycling leds
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////// Main Loop ///////////////////////////////////
|
||||
void loop () {
|
||||
do {
|
||||
successRead = getID(); // sets successRead to 1 when we get read from reader otherwise 0
|
||||
// When device is in use if wipe button pressed for 10 seconds initialize Master Card wiping
|
||||
if (digitalRead(wipeB) == LOW) { // Check if button is pressed
|
||||
// Visualize normal operation is iterrupted by pressing wipe button Red is like more Warning to user
|
||||
digitalWrite(redLed, LED_ON); // Make sure led is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure led is off
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure led is off
|
||||
// Give some feedback
|
||||
Serial.println(F("Wipe Button Pressed"));
|
||||
Serial.println(F("Master Card will be Erased! in 10 seconds"));
|
||||
bool buttonState = monitorWipeButton(10000); // Give user enough time to cancel operation
|
||||
if (buttonState == true && digitalRead(wipeB) == LOW) { // If button still be pressed, wipe EEPROM
|
||||
EEPROM.write(1, 0); // Reset Magic Number.
|
||||
Serial.println(F("Master Card Erased from device"));
|
||||
Serial.println(F("Please reset to re-program Master Card"));
|
||||
while (1);
|
||||
}
|
||||
Serial.println(F("Master Card Erase Cancelled"));
|
||||
}
|
||||
if (programMode) {
|
||||
cycleLeds(); // Program Mode cycles through Red Green Blue waiting to read a new card
|
||||
}
|
||||
else {
|
||||
normalModeOn(); // Normal mode, blue Power LED is on, all others are off
|
||||
}
|
||||
}
|
||||
while (!successRead); //the program will not go further while you are not getting a successful read
|
||||
if (programMode) {
|
||||
if ( isMaster(readCard) ) { //When in program mode check First If master card scanned again to exit program mode
|
||||
Serial.println(F("Master Card Scanned"));
|
||||
Serial.println(F("Exiting Program Mode"));
|
||||
Serial.println(F("-----------------------------"));
|
||||
programMode = false;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if ( findID(readCard) ) { // If scanned card is known delete it
|
||||
Serial.println(F("I know this PICC, removing..."));
|
||||
deleteID(readCard);
|
||||
Serial.println("-----------------------------");
|
||||
Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM"));
|
||||
}
|
||||
else { // If scanned card is not known add it
|
||||
Serial.println(F("I do not know this PICC, adding..."));
|
||||
writeID(readCard);
|
||||
Serial.println(F("-----------------------------"));
|
||||
Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( isMaster(readCard)) { // If scanned card's ID matches Master Card's ID - enter program mode
|
||||
programMode = true;
|
||||
Serial.println(F("Hello Master - Entered Program Mode"));
|
||||
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM that
|
||||
Serial.print(F("I have ")); // stores the number of ID's in EEPROM
|
||||
Serial.print(count);
|
||||
Serial.print(F(" record(s) on EEPROM"));
|
||||
Serial.println("");
|
||||
Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM"));
|
||||
Serial.println(F("Scan Master Card again to Exit Program Mode"));
|
||||
Serial.println(F("-----------------------------"));
|
||||
}
|
||||
else {
|
||||
if ( findID(readCard) ) { // If not, see if the card is in the EEPROM
|
||||
Serial.println(F("Welcome, You shall pass"));
|
||||
granted(300); // Open the door lock for 300 ms
|
||||
}
|
||||
else { // If not, show that the ID was not valid
|
||||
Serial.println(F("You shall not pass"));
|
||||
denied();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Access Granted ///////////////////////////////////
|
||||
void granted ( uint16_t setDelay) {
|
||||
digitalWrite(blueLed, LED_OFF); // Turn off blue LED
|
||||
digitalWrite(redLed, LED_OFF); // Turn off red LED
|
||||
digitalWrite(greenLed, LED_ON); // Turn on green LED
|
||||
digitalWrite(relay, LOW); // Unlock door!
|
||||
delay(setDelay); // Hold door lock open for given seconds
|
||||
digitalWrite(relay, HIGH); // Relock door
|
||||
delay(1000); // Hold green LED on for a second
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Access Denied ///////////////////////////////////
|
||||
void denied() {
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
digitalWrite(redLed, LED_ON); // Turn on red LED
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////// Get PICC's UID ///////////////////////////////////
|
||||
uint8_t getID() {
|
||||
// Getting ready for Reading PICCs
|
||||
if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
|
||||
return 0;
|
||||
}
|
||||
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
|
||||
return 0;
|
||||
}
|
||||
// There are Mifare PICCs which have 4 byte or 7 byte UID care if you use 7 byte PICC
|
||||
// I think we should assume every PICC as they have 4 byte UID
|
||||
// Until we support 7 byte PICCs
|
||||
Serial.println(F("Scanned PICC's UID:"));
|
||||
for ( uint8_t i = 0; i < 4; i++) { //
|
||||
readCard[i] = mfrc522.uid.uidByte[i];
|
||||
Serial.print(readCard[i], HEX);
|
||||
}
|
||||
Serial.println("");
|
||||
mfrc522.PICC_HaltA(); // Stop reading
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ShowReaderDetails() {
|
||||
// Get the MFRC522 software version
|
||||
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
||||
Serial.print(F("MFRC522 Software Version: 0x"));
|
||||
Serial.print(v, HEX);
|
||||
if (v == 0x91)
|
||||
Serial.print(F(" = v1.0"));
|
||||
else if (v == 0x92)
|
||||
Serial.print(F(" = v2.0"));
|
||||
else
|
||||
Serial.print(F(" (unknown),probably a chinese clone?"));
|
||||
Serial.println("");
|
||||
// When 0x00 or 0xFF is returned, communication probably failed
|
||||
if ((v == 0x00) || (v == 0xFF)) {
|
||||
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
|
||||
Serial.println(F("SYSTEM HALTED: Check connections."));
|
||||
// Visualize system is halted
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
digitalWrite(redLed, LED_ON); // Turn on red LED
|
||||
while (true); // do not go further
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Cycle Leds (Program Mode) ///////////////////////////////////
|
||||
void cycleLeds() {
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
digitalWrite(greenLed, LED_ON); // Make sure green LED is on
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
digitalWrite(blueLed, LED_ON); // Make sure blue LED is on
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_ON); // Make sure red LED is on
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
delay(200);
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Normal Mode Led ///////////////////////////////////
|
||||
void normalModeOn () {
|
||||
digitalWrite(blueLed, LED_ON); // Blue LED ON and ready to read card
|
||||
digitalWrite(redLed, LED_OFF); // Make sure Red LED is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure Green LED is off
|
||||
digitalWrite(relay, HIGH); // Make sure Door is Locked
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Read an ID from EEPROM //////////////////////////////
|
||||
void readID( uint8_t number ) {
|
||||
uint8_t start = (number * 4 ) + 2; // Figure out starting position
|
||||
for ( uint8_t i = 0; i < 4; i++ ) { // Loop 4 times to get the 4 Bytes
|
||||
storedCard[i] = EEPROM.read(start + i); // Assign values read from EEPROM to array
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Add ID to EEPROM ///////////////////////////////////
|
||||
void writeID( byte a[] ) {
|
||||
if ( !findID( a ) ) { // Before we write to the EEPROM, check to see if we have seen this card before!
|
||||
uint8_t num = EEPROM.read(0); // Get the numer of used spaces, position 0 stores the number of ID cards
|
||||
uint8_t start = ( num * 4 ) + 6; // Figure out where the next slot starts
|
||||
num++; // Increment the counter by one
|
||||
EEPROM.write( 0, num ); // Write the new count to the counter
|
||||
for ( uint8_t j = 0; j < 4; j++ ) { // Loop 4 times
|
||||
EEPROM.write( start + j, a[j] ); // Write the array values to EEPROM in the right position
|
||||
}
|
||||
successWrite();
|
||||
Serial.println(F("Succesfully added ID record to EEPROM"));
|
||||
}
|
||||
else {
|
||||
failedWrite();
|
||||
Serial.println(F("Failed! There is something wrong with ID or bad EEPROM"));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Remove ID from EEPROM ///////////////////////////////////
|
||||
void deleteID( byte a[] ) {
|
||||
if ( !findID( a ) ) { // Before we delete from the EEPROM, check to see if we have this card!
|
||||
failedWrite(); // If not
|
||||
Serial.println(F("Failed! There is something wrong with ID or bad EEPROM"));
|
||||
}
|
||||
else {
|
||||
uint8_t num = EEPROM.read(0); // Get the numer of used spaces, position 0 stores the number of ID cards
|
||||
uint8_t slot; // Figure out the slot number of the card
|
||||
uint8_t start; // = ( num * 4 ) + 6; // Figure out where the next slot starts
|
||||
uint8_t looping; // The number of times the loop repeats
|
||||
uint8_t j;
|
||||
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM that stores number of cards
|
||||
slot = findIDSLOT( a ); // Figure out the slot number of the card to delete
|
||||
start = (slot * 4) + 2;
|
||||
looping = ((num - slot) * 4);
|
||||
num--; // Decrement the counter by one
|
||||
EEPROM.write( 0, num ); // Write the new count to the counter
|
||||
for ( j = 0; j < looping; j++ ) { // Loop the card shift times
|
||||
EEPROM.write( start + j, EEPROM.read(start + 4 + j)); // Shift the array values to 4 places earlier in the EEPROM
|
||||
}
|
||||
for ( uint8_t k = 0; k < 4; k++ ) { // Shifting loop
|
||||
EEPROM.write( start + j + k, 0);
|
||||
}
|
||||
successDelete();
|
||||
Serial.println(F("Succesfully removed ID record from EEPROM"));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Check Bytes ///////////////////////////////////
|
||||
boolean checkTwo ( byte a[], byte b[] ) {
|
||||
if ( a[0] != 0 ) // Make sure there is something in the array first
|
||||
match = true; // Assume they match at first
|
||||
for ( uint8_t k = 0; k < 4; k++ ) { // Loop 4 times
|
||||
if ( a[k] != b[k] ) // IF a != b then set match = false, one fails, all fail
|
||||
match = false;
|
||||
}
|
||||
if ( match ) { // Check to see if if match is still true
|
||||
return true; // Return true
|
||||
}
|
||||
else {
|
||||
return false; // Return false
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Find Slot ///////////////////////////////////
|
||||
uint8_t findIDSLOT( byte find[] ) {
|
||||
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM that
|
||||
for ( uint8_t i = 1; i <= count; i++ ) { // Loop once for each EEPROM entry
|
||||
readID(i); // Read an ID from EEPROM, it is stored in storedCard[4]
|
||||
if ( checkTwo( find, storedCard ) ) { // Check to see if the storedCard read from EEPROM
|
||||
// is the same as the find[] ID card passed
|
||||
return i; // The slot number of the card
|
||||
break; // Stop looking we found it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Find ID From EEPROM ///////////////////////////////////
|
||||
boolean findID( byte find[] ) {
|
||||
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM that
|
||||
for ( uint8_t i = 1; i < count; i++ ) { // Loop once for each EEPROM entry
|
||||
readID(i); // Read an ID from EEPROM, it is stored in storedCard[4]
|
||||
if ( checkTwo( find, storedCard ) ) { // Check to see if the storedCard read from EEPROM
|
||||
return true;
|
||||
break; // Stop looking we found it
|
||||
}
|
||||
else { // If not, return false
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Write Success to EEPROM ///////////////////////////////////
|
||||
// Flashes the green LED 3 times to indicate a successful write to EEPROM
|
||||
void successWrite() {
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is on
|
||||
delay(200);
|
||||
digitalWrite(greenLed, LED_ON); // Make sure green LED is on
|
||||
delay(200);
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
delay(200);
|
||||
digitalWrite(greenLed, LED_ON); // Make sure green LED is on
|
||||
delay(200);
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
delay(200);
|
||||
digitalWrite(greenLed, LED_ON); // Make sure green LED is on
|
||||
delay(200);
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Write Failed to EEPROM ///////////////////////////////////
|
||||
// Flashes the red LED 3 times to indicate a failed write to EEPROM
|
||||
void failedWrite() {
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_ON); // Make sure red LED is on
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_ON); // Make sure red LED is on
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
delay(200);
|
||||
digitalWrite(redLed, LED_ON); // Make sure red LED is on
|
||||
delay(200);
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Success Remove UID From EEPROM ///////////////////////////////////
|
||||
// Flashes the blue LED 3 times to indicate a success delete to EEPROM
|
||||
void successDelete() {
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
digitalWrite(redLed, LED_OFF); // Make sure red LED is off
|
||||
digitalWrite(greenLed, LED_OFF); // Make sure green LED is off
|
||||
delay(200);
|
||||
digitalWrite(blueLed, LED_ON); // Make sure blue LED is on
|
||||
delay(200);
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
delay(200);
|
||||
digitalWrite(blueLed, LED_ON); // Make sure blue LED is on
|
||||
delay(200);
|
||||
digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off
|
||||
delay(200);
|
||||
digitalWrite(blueLed, LED_ON); // Make sure blue LED is on
|
||||
delay(200);
|
||||
}
|
||||
|
||||
////////////////////// Check readCard IF is masterCard ///////////////////////////////////
|
||||
// Check to see if the ID passed is the master programing card
|
||||
boolean isMaster( byte test[] ) {
|
||||
if ( checkTwo( test, masterCard ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool monitorWipeButton(uint32_t interval) {
|
||||
uint32_t now = (uint32_t)millis();
|
||||
while ((uint32_t)millis() - now < interval) {
|
||||
// check on every half a second
|
||||
if (((uint32_t)millis() % 500) == 0) {
|
||||
if (digitalRead(wipeB) != LOW)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
112
projects/rfid/examples/ChangeUID/ChangeUID.ino
Normal file
112
projects/rfid/examples/ChangeUID/ChangeUID.ino
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example to change UID of changeable MIFARE card.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
|
||||
*
|
||||
* This sample shows how to set the UID on a UID changeable MIFARE card.
|
||||
* NOTE: for more informations read the README.rst
|
||||
*
|
||||
* @author Tom Clement
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <MFRC522.h>
|
||||
#include <MFRC522Hack.h>
|
||||
|
||||
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
|
||||
constexpr uint8_t SS_PIN = 10; // Configurable, see typical pin layout above
|
||||
|
||||
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
|
||||
MFRC522Hack mfrc522Hack(&mfrc522); // Create MFRC522Hack instance.
|
||||
|
||||
/* Set your new UID here! */
|
||||
byte newUid[] = {0xDE, 0xAD, 0xBE, 0xEF};
|
||||
|
||||
MFRC522::MIFARE_Key key;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // Initialize serial communications with the PC
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
|
||||
SPI.begin(); // Init SPI bus
|
||||
mfrc522.PCD_Init(); // Init MFRC522 card
|
||||
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
|
||||
|
||||
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
|
||||
for (byte i = 0; i < 6; i++) {
|
||||
key.keyByte[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the UID can be as simple as this:
|
||||
//void loop() {
|
||||
// byte newUid[] = NEW_UID;
|
||||
// if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
|
||||
// Serial.println("Wrote new UID to card.");
|
||||
// }
|
||||
// delay(1000);
|
||||
//}
|
||||
|
||||
// But of course this is a more proper approach
|
||||
void loop() {
|
||||
|
||||
// Look for new cards, and select one if present
|
||||
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
|
||||
delay(50);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now a card is selected. The UID and SAK is in mfrc522.uid.
|
||||
|
||||
// Dump UID
|
||||
Serial.print(F("Card UID:"));
|
||||
for (byte i = 0; i < mfrc522.uid.size; i++) {
|
||||
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
|
||||
Serial.print(mfrc522.uid.uidByte[i], HEX);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Dump PICC type
|
||||
// MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
|
||||
// Serial.print(F("PICC type: "));
|
||||
// Serial.print(mfrc522.PICC_GetTypeName(piccType));
|
||||
// Serial.print(F(" (SAK "));
|
||||
// Serial.print(mfrc522.uid.sak);
|
||||
// Serial.print(")\r\n");
|
||||
// if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
|
||||
// && piccType != MFRC522::PICC_TYPE_MIFARE_1K
|
||||
// && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
|
||||
// Serial.println(F("This sample only works with MIFARE Classic cards."));
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Set new UID
|
||||
if ( mfrc522Hack.MIFARE_SetUid(newUid, (byte)4, true) ) {
|
||||
Serial.println(F("Wrote new UID to card."));
|
||||
}
|
||||
|
||||
// Halt PICC and re-select it so DumpToSerial doesn't get confused
|
||||
mfrc522.PICC_HaltA();
|
||||
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump the new memory contents
|
||||
Serial.println(F("New UID and contents:"));
|
||||
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
|
||||
|
||||
delay(2000);
|
||||
}
|
66
projects/rfid/examples/DumpInfo/DumpInfo.ino
Normal file
66
projects/rfid/examples/DumpInfo/DumpInfo.ino
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example sketch/program showing how to read data from a PICC to serial.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
|
||||
*
|
||||
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
|
||||
* Reader on the Arduino SPI interface.
|
||||
*
|
||||
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
|
||||
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
|
||||
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
|
||||
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
|
||||
* when removing the PICC from reading distance too early.
|
||||
*
|
||||
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
|
||||
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
|
||||
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
|
||||
* keep the PICCs at reading distance until complete.
|
||||
*
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <MFRC522.h>
|
||||
|
||||
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
|
||||
constexpr uint8_t SS_PIN = 10; // Configurable, see typical pin layout above
|
||||
|
||||
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // Initialize serial communications with the PC
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
|
||||
SPI.begin(); // Init SPI bus
|
||||
mfrc522.PCD_Init(); // Init MFRC522
|
||||
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
|
||||
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Look for new cards
|
||||
if ( ! mfrc522.PICC_IsNewCardPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Select one of the cards
|
||||
if ( ! mfrc522.PICC_ReadCardSerial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump debug info about the card; PICC_HaltA() is automatically called
|
||||
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
|
||||
}
|
55
projects/rfid/examples/FixBrickedUID/FixBrickedUID.ino
Normal file
55
projects/rfid/examples/FixBrickedUID/FixBrickedUID.ino
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example sketch/program to fix a broken UID changeable MIFARE cards.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
|
||||
*
|
||||
* This sample shows how to fix a broken UID changeable MIFARE cards that have a corrupted sector 0.
|
||||
*
|
||||
* @author Tom Clement
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <MFRC522.h>
|
||||
#include <MFRC522Hack.h>
|
||||
|
||||
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
|
||||
constexpr uint8_t SS_PIN = 10; // Configurable, see typical pin layout above
|
||||
|
||||
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
|
||||
MFRC522Hack mfrc522Hack(&mfrc522); // Create MFRC522Hack instance.
|
||||
|
||||
MFRC522::MIFARE_Key key;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // Initialize serial communications with the PC
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
|
||||
SPI.begin(); // Init SPI bus
|
||||
mfrc522.PCD_Init(); // Init MFRC522 card
|
||||
Serial.println(F("Warning: this example clears your mifare UID, use with care!"));
|
||||
|
||||
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
|
||||
for (byte i = 0; i < 6; i++) {
|
||||
key.keyByte[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if ( mfrc522Hack.MIFARE_UnbrickUidSector(false) ) {
|
||||
Serial.println(F("Cleared sector 0, set UID to 1234. Card should be responsive again now."));
|
||||
}
|
||||
delay(1000);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user