move libraries under projects because that'S what they are used for
This commit is contained in:
parent
0d8df19c70
commit
cd3442d96e
24
libraries/Debug/Debug.h
Normal file
24
libraries/Debug/Debug.h
Normal file
@ -0,0 +1,24 @@
|
||||
#include <SoftwareSerial_Tiny.h>
|
||||
|
||||
#if DEBUG
|
||||
#define RxD 0
|
||||
#define TxD 4
|
||||
SoftwareSerial AttinySerial(RxD,TxD);
|
||||
#endif
|
||||
|
||||
class Debug {
|
||||
|
||||
public:
|
||||
void setup() {
|
||||
#if DEBUG
|
||||
AttinySerial.begin(9600);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print(const char* msg) {
|
||||
#if DEBUG
|
||||
AttinySerial.println(msg);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
826
libraries/RCSwitch_Tiny/RCSwitch_Tiny.cpp
Normal file
826
libraries/RCSwitch_Tiny/RCSwitch_Tiny.cpp
Normal file
@ -0,0 +1,826 @@
|
||||
/*
|
||||
RCSwitch - Arduino libary for remote control outlet switches
|
||||
Copyright (c) 2011 Suat Özgür. All right reserved.
|
||||
|
||||
Contributors:
|
||||
- Andre Koehler / info(at)tomate-online(dot)de
|
||||
- Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com
|
||||
- Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46
|
||||
- Dominik Fischer / dom_fischer(at)web(dot)de
|
||||
- Frank Oltmanns / <first name>.<last name>(at)gmail(dot)com
|
||||
- Andreas Steinel / A.<lastname>(at)gmail(dot)com
|
||||
|
||||
Project home: http://code.google.com/p/rc-switch/
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include "RCSwitch_Tiny.h"
|
||||
#include "PinChangeInterrupt.h"
|
||||
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
unsigned long RCSwitch::nReceivedValue = NULL;
|
||||
unsigned int RCSwitch::nReceivedBitlength = 0;
|
||||
unsigned int RCSwitch::nReceivedDelay = 0;
|
||||
unsigned int RCSwitch::nReceivedProtocol = 0;
|
||||
int RCSwitch::nReceiveTolerance = 60;
|
||||
#endif
|
||||
unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES];
|
||||
|
||||
RCSwitch::RCSwitch() {
|
||||
this->nTransmitterPin = -1;
|
||||
this->setPulseLength(350);
|
||||
this->setRepeatTransmit(10);
|
||||
this->setProtocol(1);
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
this->nReceiverInterrupt = -1;
|
||||
this->setReceiveTolerance(60);
|
||||
RCSwitch::nReceivedValue = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the protocol to send.
|
||||
*/
|
||||
void RCSwitch::setProtocol(int nProtocol) {
|
||||
this->nProtocol = nProtocol;
|
||||
if (nProtocol == 1){
|
||||
this->setPulseLength(350);
|
||||
}
|
||||
else if (nProtocol == 2) {
|
||||
this->setPulseLength(650);
|
||||
}
|
||||
else if (nProtocol == 3) {
|
||||
this->setPulseLength(100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the protocol to send with pulse length in microseconds.
|
||||
*/
|
||||
void RCSwitch::setProtocol(int nProtocol, int nPulseLength) {
|
||||
this->nProtocol = nProtocol;
|
||||
this->setPulseLength(nPulseLength);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets pulse length in microseconds
|
||||
*/
|
||||
void RCSwitch::setPulseLength(int nPulseLength) {
|
||||
this->nPulseLength = nPulseLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Repeat Transmits
|
||||
*/
|
||||
void RCSwitch::setRepeatTransmit(int nRepeatTransmit) {
|
||||
this->nRepeatTransmit = nRepeatTransmit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Receiving Tolerance
|
||||
*/
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
void RCSwitch::setReceiveTolerance(int nPercent) {
|
||||
RCSwitch::nReceiveTolerance = nPercent;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Enable transmissions
|
||||
*
|
||||
* @param nTransmitterPin Arduino Pin to which the sender is connected to
|
||||
*/
|
||||
void RCSwitch::enableTransmit(int nTransmitterPin) {
|
||||
this->nTransmitterPin = nTransmitterPin;
|
||||
pinMode(this->nTransmitterPin, OUTPUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable transmissions
|
||||
*/
|
||||
void RCSwitch::disableTransmit() {
|
||||
this->nTransmitterPin = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch on (Type D REV)
|
||||
*
|
||||
* @param sGroup Code of the switch group (A,B,C,D)
|
||||
* @param nDevice Number of the switch itself (1..3)
|
||||
*/
|
||||
void RCSwitch::switchOn(char sGroup, int nDevice) {
|
||||
this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch off (Type D REV)
|
||||
*
|
||||
* @param sGroup Code of the switch group (A,B,C,D)
|
||||
* @param nDevice Number of the switch itself (1..3)
|
||||
*/
|
||||
void RCSwitch::switchOff(char sGroup, int nDevice) {
|
||||
this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch on (Type C Intertechno)
|
||||
*
|
||||
* @param sFamily Familycode (a..f)
|
||||
* @param nGroup Number of group (1..4)
|
||||
* @param nDevice Number of device (1..4)
|
||||
*/
|
||||
void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) {
|
||||
this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch off (Type C Intertechno)
|
||||
*
|
||||
* @param sFamily Familycode (a..f)
|
||||
* @param nGroup Number of group (1..4)
|
||||
* @param nDevice Number of device (1..4)
|
||||
*/
|
||||
void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) {
|
||||
this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch on (Type B with two rotary/sliding switches)
|
||||
*
|
||||
* @param nAddressCode Number of the switch group (1..4)
|
||||
* @param nChannelCode Number of the switch itself (1..4)
|
||||
*/
|
||||
void RCSwitch::switchOn(int nAddressCode, int nChannelCode) {
|
||||
this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch off (Type B with two rotary/sliding switches)
|
||||
*
|
||||
* @param nAddressCode Number of the switch group (1..4)
|
||||
* @param nChannelCode Number of the switch itself (1..4)
|
||||
*/
|
||||
void RCSwitch::switchOff(int nAddressCode, int nChannelCode) {
|
||||
this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use switchOn(char* sGroup, char* sDevice) instead!
|
||||
* Switch a remote switch on (Type A with 10 pole DIP switches)
|
||||
*
|
||||
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
|
||||
* @param nChannelCode Number of the switch itself (1..5)
|
||||
*/
|
||||
void RCSwitch::switchOn(char* sGroup, int nChannel) {
|
||||
char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" };
|
||||
this->switchOn(sGroup, code[nChannel]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use switchOff(char* sGroup, char* sDevice) instead!
|
||||
* Switch a remote switch off (Type A with 10 pole DIP switches)
|
||||
*
|
||||
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
|
||||
* @param nChannelCode Number of the switch itself (1..5)
|
||||
*/
|
||||
void RCSwitch::switchOff(char* sGroup, int nChannel) {
|
||||
char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" };
|
||||
this->switchOff(sGroup, code[nChannel]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch on (Type A with 10 pole DIP switches)
|
||||
*
|
||||
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
|
||||
* @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111")
|
||||
*/
|
||||
void RCSwitch::switchOn(char* sGroup, char* sDevice) {
|
||||
this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a remote switch off (Type A with 10 pole DIP switches)
|
||||
*
|
||||
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
|
||||
* @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111")
|
||||
*/
|
||||
void RCSwitch::switchOff(char* sGroup, char* sDevice) {
|
||||
this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a char[13], representing the Code Word to be send.
|
||||
* A Code Word consists of 9 address bits, 3 data bits and one sync bit but in our case only the first 8 address bits and the last 2 data bits were used.
|
||||
* A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit)
|
||||
*
|
||||
* +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+
|
||||
* | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit |
|
||||
* | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S |
|
||||
* +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+
|
||||
*
|
||||
* @param nAddressCode Number of the switch group (1..4)
|
||||
* @param nChannelCode Number of the switch itself (1..4)
|
||||
* @param bStatus Wether to switch on (true) or off (false)
|
||||
*
|
||||
* @return char[13]
|
||||
*/
|
||||
char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) {
|
||||
int nReturnPos = 0;
|
||||
static char sReturn[13];
|
||||
|
||||
char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" };
|
||||
if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) {
|
||||
return '\0';
|
||||
}
|
||||
for (int i = 0; i<4; i++) {
|
||||
sReturn[nReturnPos++] = code[nAddressCode][i];
|
||||
}
|
||||
|
||||
for (int i = 0; i<4; i++) {
|
||||
sReturn[nReturnPos++] = code[nChannelCode][i];
|
||||
}
|
||||
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
|
||||
if (bStatus) {
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
} else {
|
||||
sReturn[nReturnPos++] = '0';
|
||||
}
|
||||
|
||||
sReturn[nReturnPos] = '\0';
|
||||
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a char[13], representing the Code Word to be send.
|
||||
*
|
||||
* getCodeWordA(char*, char*)
|
||||
*
|
||||
*/
|
||||
char* RCSwitch::getCodeWordA(char* sGroup, char* sDevice, boolean bOn) {
|
||||
static char sDipSwitches[13];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
for (i=0; i < 5; i++) {
|
||||
if (sGroup[i] == '0') {
|
||||
sDipSwitches[j++] = 'F';
|
||||
} else {
|
||||
sDipSwitches[j++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < 5; i++) {
|
||||
if (sDevice[i] == '0') {
|
||||
sDipSwitches[j++] = 'F';
|
||||
} else {
|
||||
sDipSwitches[j++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
if ( bOn ) {
|
||||
sDipSwitches[j++] = '0';
|
||||
sDipSwitches[j++] = 'F';
|
||||
} else {
|
||||
sDipSwitches[j++] = 'F';
|
||||
sDipSwitches[j++] = '0';
|
||||
}
|
||||
|
||||
sDipSwitches[j] = '\0';
|
||||
|
||||
return sDipSwitches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like getCodeWord (Type C = Intertechno)
|
||||
*/
|
||||
char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus) {
|
||||
static char sReturn[13];
|
||||
int nReturnPos = 0;
|
||||
|
||||
if ( (byte)sFamily < 97 || (byte)sFamily > 112 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) {
|
||||
return '\0';
|
||||
}
|
||||
|
||||
char* sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 );
|
||||
char familycode[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" };
|
||||
for (int i = 0; i<4; i++) {
|
||||
sReturn[nReturnPos++] = familycode[ (int)sFamily - 97 ][i];
|
||||
}
|
||||
for (int i = 0; i<4; i++) {
|
||||
sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0');
|
||||
}
|
||||
sReturn[nReturnPos++] = '0';
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
if (bStatus) {
|
||||
sReturn[nReturnPos++] = 'F';
|
||||
} else {
|
||||
sReturn[nReturnPos++] = '0';
|
||||
}
|
||||
sReturn[nReturnPos] = '\0';
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoding for the REV Switch Type
|
||||
*
|
||||
* Returns a char[13], representing the Tristate to be send.
|
||||
* A Code Word consists of 7 address bits and 5 command data bits.
|
||||
* A Code Bit can have 3 different states: "F" (floating), "0" (low), "1" (high)
|
||||
*
|
||||
* +-------------------------------+--------------------------------+-----------------------+
|
||||
* | 4 bits address (switch group) | 3 bits address (device number) | 5 bits (command data) |
|
||||
* | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | on=00010 off=00001 |
|
||||
* +-------------------------------+--------------------------------+-----------------------+
|
||||
*
|
||||
* Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/
|
||||
*
|
||||
* @param sGroup Name of the switch group (A..D, resp. a..d)
|
||||
* @param nDevice Number of the switch itself (1..3)
|
||||
* @param bStatus Wether to switch on (true) or off (false)
|
||||
*
|
||||
* @return char[13]
|
||||
*/
|
||||
|
||||
char* RCSwitch::getCodeWordD(char sGroup, int nDevice, boolean bStatus){
|
||||
static char sReturn[13];
|
||||
int nReturnPos = 0;
|
||||
|
||||
// Building 4 bits address
|
||||
// (Potential problem if dec2binWcharfill not returning correct string)
|
||||
char *sGroupCode;
|
||||
switch(sGroup){
|
||||
case 'a':
|
||||
case 'A':
|
||||
sGroupCode = dec2binWcharfill(8, 4, 'F'); break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
sGroupCode = dec2binWcharfill(4, 4, 'F'); break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
sGroupCode = dec2binWcharfill(2, 4, 'F'); break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
sGroupCode = dec2binWcharfill(1, 4, 'F'); break;
|
||||
default:
|
||||
return '\0';
|
||||
}
|
||||
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
sReturn[nReturnPos++] = sGroupCode[i];
|
||||
}
|
||||
|
||||
|
||||
// Building 3 bits address
|
||||
// (Potential problem if dec2binWcharfill not returning correct string)
|
||||
char *sDevice;
|
||||
switch(nDevice) {
|
||||
case 1:
|
||||
sDevice = dec2binWcharfill(4, 3, 'F'); break;
|
||||
case 2:
|
||||
sDevice = dec2binWcharfill(2, 3, 'F'); break;
|
||||
case 3:
|
||||
sDevice = dec2binWcharfill(1, 3, 'F'); break;
|
||||
default:
|
||||
return '\0';
|
||||
}
|
||||
|
||||
for (int i = 0; i<3; i++)
|
||||
sReturn[nReturnPos++] = sDevice[i];
|
||||
|
||||
// fill up rest with zeros
|
||||
for (int i = 0; i<5; i++)
|
||||
sReturn[nReturnPos++] = '0';
|
||||
|
||||
// encode on or off
|
||||
if (bStatus)
|
||||
sReturn[10] = '1';
|
||||
else
|
||||
sReturn[11] = '1';
|
||||
|
||||
// last position terminate string
|
||||
sReturn[12] = '\0';
|
||||
return sReturn;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sCodeWord /^[10FS]*$/ -> see getCodeWord
|
||||
*/
|
||||
void RCSwitch::sendTriState(char* sCodeWord) {
|
||||
for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) {
|
||||
int i = 0;
|
||||
while (sCodeWord[i] != '\0') {
|
||||
switch(sCodeWord[i]) {
|
||||
case '0':
|
||||
this->sendT0();
|
||||
break;
|
||||
case 'F':
|
||||
this->sendTF();
|
||||
break;
|
||||
case '1':
|
||||
this->sendT1();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this->sendSync();
|
||||
}
|
||||
}
|
||||
|
||||
void RCSwitch::send(unsigned long Code, unsigned int length) {
|
||||
this->send( this->dec2binWzerofill(Code, length) );
|
||||
}
|
||||
|
||||
void RCSwitch::send(char* sCodeWord) {
|
||||
for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) {
|
||||
int i = 0;
|
||||
while (sCodeWord[i] != '\0') {
|
||||
switch(sCodeWord[i]) {
|
||||
case '0':
|
||||
this->send0();
|
||||
break;
|
||||
case '1':
|
||||
this->send1();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this->sendSync();
|
||||
}
|
||||
}
|
||||
|
||||
void RCSwitch::transmit(int nHighPulses, int nLowPulses) {
|
||||
#if not defined ( RCSwitchDisableReceiving )
|
||||
boolean disabled_Receive = false;
|
||||
int nReceiverInterrupt_backup = nReceiverInterrupt;
|
||||
#endif
|
||||
if (this->nTransmitterPin != -1) {
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
if (this->nReceiverInterrupt != -1) {
|
||||
this->disableReceive();
|
||||
disabled_Receive = true;
|
||||
}
|
||||
#endif
|
||||
digitalWrite(this->nTransmitterPin, HIGH);
|
||||
delayMicroseconds( this->nPulseLength * nHighPulses);
|
||||
digitalWrite(this->nTransmitterPin, LOW);
|
||||
delayMicroseconds( this->nPulseLength * nLowPulses);
|
||||
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
if(disabled_Receive){
|
||||
this->enableReceive(nReceiverInterrupt_backup);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sends a "0" Bit
|
||||
* _
|
||||
* Waveform Protocol 1: | |___
|
||||
* _
|
||||
* Waveform Protocol 2: | |__
|
||||
*/
|
||||
void RCSwitch::send0() {
|
||||
if (this->nProtocol == 1){
|
||||
this->transmit(1,3);
|
||||
}
|
||||
else if (this->nProtocol == 2) {
|
||||
this->transmit(1,2);
|
||||
}
|
||||
else if (this->nProtocol == 3) {
|
||||
this->transmit(4,11);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a "1" Bit
|
||||
* ___
|
||||
* Waveform Protocol 1: | |_
|
||||
* __
|
||||
* Waveform Protocol 2: | |_
|
||||
*/
|
||||
void RCSwitch::send1() {
|
||||
if (this->nProtocol == 1){
|
||||
this->transmit(3,1);
|
||||
}
|
||||
else if (this->nProtocol == 2) {
|
||||
this->transmit(2,1);
|
||||
}
|
||||
else if (this->nProtocol == 3) {
|
||||
this->transmit(9,6);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a Tri-State "0" Bit
|
||||
* _ _
|
||||
* Waveform: | |___| |___
|
||||
*/
|
||||
void RCSwitch::sendT0() {
|
||||
this->transmit(1,3);
|
||||
this->transmit(1,3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Tri-State "1" Bit
|
||||
* ___ ___
|
||||
* Waveform: | |_| |_
|
||||
*/
|
||||
void RCSwitch::sendT1() {
|
||||
this->transmit(3,1);
|
||||
this->transmit(3,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Tri-State "F" Bit
|
||||
* _ ___
|
||||
* Waveform: | |___| |_
|
||||
*/
|
||||
void RCSwitch::sendTF() {
|
||||
this->transmit(1,3);
|
||||
this->transmit(3,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a "Sync" Bit
|
||||
* _
|
||||
* Waveform Protocol 1: | |_______________________________
|
||||
* _
|
||||
* Waveform Protocol 2: | |__________
|
||||
*/
|
||||
void RCSwitch::sendSync() {
|
||||
|
||||
if (this->nProtocol == 1){
|
||||
this->transmit(1,31);
|
||||
}
|
||||
else if (this->nProtocol == 2) {
|
||||
this->transmit(1,10);
|
||||
}
|
||||
else if (this->nProtocol == 3) {
|
||||
this->transmit(1,71);
|
||||
}
|
||||
}
|
||||
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
/**
|
||||
* Enable receiving data
|
||||
*/
|
||||
void RCSwitch::enableReceive(int interrupt) {
|
||||
this->nReceiverInterrupt = interrupt;
|
||||
this->enableReceive();
|
||||
}
|
||||
|
||||
void RCSwitch::enableReceive() {
|
||||
if (this->nReceiverInterrupt != -1) {
|
||||
RCSwitch::nReceivedValue = NULL;
|
||||
RCSwitch::nReceivedBitlength = NULL;
|
||||
// attachInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE);
|
||||
attachPinChangeInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable receiving data
|
||||
*/
|
||||
void RCSwitch::disableReceive() {
|
||||
detachInterrupt(this->nReceiverInterrupt);
|
||||
this->nReceiverInterrupt = -1;
|
||||
}
|
||||
|
||||
bool RCSwitch::available() {
|
||||
return RCSwitch::nReceivedValue != NULL;
|
||||
}
|
||||
|
||||
void RCSwitch::resetAvailable() {
|
||||
RCSwitch::nReceivedValue = NULL;
|
||||
}
|
||||
|
||||
unsigned long RCSwitch::getReceivedValue() {
|
||||
return RCSwitch::nReceivedValue;
|
||||
}
|
||||
|
||||
unsigned int RCSwitch::getReceivedBitlength() {
|
||||
return RCSwitch::nReceivedBitlength;
|
||||
}
|
||||
|
||||
unsigned int RCSwitch::getReceivedDelay() {
|
||||
return RCSwitch::nReceivedDelay;
|
||||
}
|
||||
|
||||
unsigned int RCSwitch::getReceivedProtocol() {
|
||||
return RCSwitch::nReceivedProtocol;
|
||||
}
|
||||
|
||||
unsigned int* RCSwitch::getReceivedRawdata() {
|
||||
return RCSwitch::timings;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
bool RCSwitch::receiveProtocol1(unsigned int changeCount){
|
||||
|
||||
unsigned long code = 0;
|
||||
unsigned long delay = RCSwitch::timings[0] / 31;
|
||||
unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01;
|
||||
|
||||
for (int i = 1; i<changeCount ; i=i+2) {
|
||||
|
||||
if (RCSwitch::timings[i] > delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*3-delayTolerance && RCSwitch::timings[i+1] < delay*3+delayTolerance) {
|
||||
code = code << 1;
|
||||
} else if (RCSwitch::timings[i] > delay*3-delayTolerance && RCSwitch::timings[i] < delay*3+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) {
|
||||
code+=1;
|
||||
code = code << 1;
|
||||
} else {
|
||||
// Failed
|
||||
i = changeCount;
|
||||
code = 0;
|
||||
}
|
||||
}
|
||||
code = code >> 1;
|
||||
if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise
|
||||
RCSwitch::nReceivedValue = code;
|
||||
RCSwitch::nReceivedBitlength = changeCount / 2;
|
||||
RCSwitch::nReceivedDelay = delay;
|
||||
RCSwitch::nReceivedProtocol = 1;
|
||||
}
|
||||
|
||||
if (code == 0){
|
||||
return false;
|
||||
}else if (code != 0){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool RCSwitch::receiveProtocol2(unsigned int changeCount){
|
||||
|
||||
unsigned long code = 0;
|
||||
unsigned long delay = RCSwitch::timings[0] / 10;
|
||||
unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01;
|
||||
|
||||
for (int i = 1; i<changeCount ; i=i+2) {
|
||||
|
||||
if (RCSwitch::timings[i] > delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*2-delayTolerance && RCSwitch::timings[i+1] < delay*2+delayTolerance) {
|
||||
code = code << 1;
|
||||
} else if (RCSwitch::timings[i] > delay*2-delayTolerance && RCSwitch::timings[i] < delay*2+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) {
|
||||
code+=1;
|
||||
code = code << 1;
|
||||
} else {
|
||||
// Failed
|
||||
i = changeCount;
|
||||
code = 0;
|
||||
}
|
||||
}
|
||||
code = code >> 1;
|
||||
if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise
|
||||
RCSwitch::nReceivedValue = code;
|
||||
RCSwitch::nReceivedBitlength = changeCount / 2;
|
||||
RCSwitch::nReceivedDelay = delay;
|
||||
RCSwitch::nReceivedProtocol = 2;
|
||||
}
|
||||
|
||||
if (code == 0){
|
||||
return false;
|
||||
}else if (code != 0){
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Protocol 3 is used by BL35P02.
|
||||
*
|
||||
*/
|
||||
bool RCSwitch::receiveProtocol3(unsigned int changeCount){
|
||||
|
||||
unsigned long code = 0;
|
||||
unsigned long delay = RCSwitch::timings[0] / PROTOCOL3_SYNC_FACTOR;
|
||||
unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01;
|
||||
|
||||
for (int i = 1; i<changeCount ; i=i+2) {
|
||||
|
||||
if (RCSwitch::timings[i] > delay*PROTOCOL3_0_HIGH_CYCLES - delayTolerance
|
||||
&& RCSwitch::timings[i] < delay*PROTOCOL3_0_HIGH_CYCLES + delayTolerance
|
||||
&& RCSwitch::timings[i+1] > delay*PROTOCOL3_0_LOW_CYCLES - delayTolerance
|
||||
&& RCSwitch::timings[i+1] < delay*PROTOCOL3_0_LOW_CYCLES + delayTolerance) {
|
||||
code = code << 1;
|
||||
} else if (RCSwitch::timings[i] > delay*PROTOCOL3_1_HIGH_CYCLES - delayTolerance
|
||||
&& RCSwitch::timings[i] < delay*PROTOCOL3_1_HIGH_CYCLES + delayTolerance
|
||||
&& RCSwitch::timings[i+1] > delay*PROTOCOL3_1_LOW_CYCLES - delayTolerance
|
||||
&& RCSwitch::timings[i+1] < delay*PROTOCOL3_1_LOW_CYCLES + delayTolerance) {
|
||||
code+=1;
|
||||
code = code << 1;
|
||||
} else {
|
||||
// Failed
|
||||
i = changeCount;
|
||||
code = 0;
|
||||
}
|
||||
}
|
||||
code = code >> 1;
|
||||
if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise
|
||||
RCSwitch::nReceivedValue = code;
|
||||
RCSwitch::nReceivedBitlength = changeCount / 2;
|
||||
RCSwitch::nReceivedDelay = delay;
|
||||
RCSwitch::nReceivedProtocol = 3;
|
||||
}
|
||||
|
||||
if (code == 0){
|
||||
return false;
|
||||
}else if (code != 0){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void RCSwitch::handleInterrupt() {
|
||||
|
||||
static unsigned int duration;
|
||||
static unsigned int changeCount;
|
||||
static unsigned long lastTime;
|
||||
static unsigned int repeatCount;
|
||||
|
||||
|
||||
long time = micros();
|
||||
duration = time - lastTime;
|
||||
|
||||
|
||||
if (duration > 5000 && duration > RCSwitch::timings[0] - 200 && duration < RCSwitch::timings[0] + 200) {
|
||||
repeatCount++;
|
||||
changeCount--;
|
||||
if (repeatCount == 2) {
|
||||
if (receiveProtocol1(changeCount) == false){
|
||||
if (receiveProtocol2(changeCount) == false){
|
||||
if (receiveProtocol3(changeCount) == false){
|
||||
//failed
|
||||
}
|
||||
}
|
||||
}
|
||||
repeatCount = 0;
|
||||
}
|
||||
changeCount = 0;
|
||||
} else if (duration > 5000) {
|
||||
changeCount = 0;
|
||||
}
|
||||
|
||||
if (changeCount >= RCSWITCH_MAX_CHANGES) {
|
||||
changeCount = 0;
|
||||
repeatCount = 0;
|
||||
}
|
||||
RCSwitch::timings[changeCount++] = duration;
|
||||
lastTime = time;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Turns a decimal value to its binary representation
|
||||
*/
|
||||
char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){
|
||||
return dec2binWcharfill(Dec, bitLength, '0');
|
||||
}
|
||||
|
||||
char* RCSwitch::dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill){
|
||||
static char bin[64];
|
||||
unsigned int i=0;
|
||||
|
||||
while (Dec > 0) {
|
||||
bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill;
|
||||
Dec = Dec >> 1;
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j< bitLength; j++) {
|
||||
if (j >= bitLength - i) {
|
||||
bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
|
||||
}else {
|
||||
bin[j] = fill;
|
||||
}
|
||||
}
|
||||
bin[bitLength] = '\0';
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
144
libraries/RCSwitch_Tiny/RCSwitch_Tiny.h
Normal file
144
libraries/RCSwitch_Tiny/RCSwitch_Tiny.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
RCSwitch - Arduino libary for remote control outlet switches
|
||||
Copyright (c) 2011 Suat Özgür. All right reserved.
|
||||
|
||||
Contributors:
|
||||
- Andre Koehler / info(at)tomate-online(dot)de
|
||||
- Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com
|
||||
- Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46
|
||||
- Dominik Fischer / dom_fischer(at)web(dot)de
|
||||
- Frank Oltmanns / <first name>.<last name>(at)gmail(dot)com
|
||||
|
||||
Project home: http://code.google.com/p/rc-switch/
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef _RCSwitch_h
|
||||
#define _RCSwitch_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific
|
||||
#include "Energia.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
|
||||
// At least for the ATTiny X4/X5, receiving has to be disabled due to
|
||||
// missing libm depencies (udivmodhi4)
|
||||
#if defined( __AVR_ATtinyX5__ ) or defined ( __AVR_ATtinyX4__ )
|
||||
#define RCSwitchDisableReceiving
|
||||
#endif
|
||||
|
||||
// Number of maximum High/Low changes per packet.
|
||||
// We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync
|
||||
#define RCSWITCH_MAX_CHANGES 67
|
||||
|
||||
#define PROTOCOL3_SYNC_FACTOR 71
|
||||
#define PROTOCOL3_0_HIGH_CYCLES 4
|
||||
#define PROTOCOL3_0_LOW_CYCLES 11
|
||||
#define PROTOCOL3_1_HIGH_CYCLES 9
|
||||
#define PROTOCOL3_1_LOW_CYCLES 6
|
||||
|
||||
class RCSwitch {
|
||||
|
||||
public:
|
||||
RCSwitch();
|
||||
|
||||
void switchOn(int nGroupNumber, int nSwitchNumber);
|
||||
void switchOff(int nGroupNumber, int nSwitchNumber);
|
||||
void switchOn(char* sGroup, int nSwitchNumber);
|
||||
void switchOff(char* sGroup, int nSwitchNumber);
|
||||
void switchOn(char sFamily, int nGroup, int nDevice);
|
||||
void switchOff(char sFamily, int nGroup, int nDevice);
|
||||
void switchOn(char* sGroup, char* sDevice);
|
||||
void switchOff(char* sGroup, char* sDevice);
|
||||
void switchOn(char sGroup, int nDevice);
|
||||
void switchOff(char sGroup, int nDevice);
|
||||
|
||||
void sendTriState(char* Code);
|
||||
void send(unsigned long Code, unsigned int length);
|
||||
void send(char* Code);
|
||||
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
void enableReceive(int interrupt);
|
||||
void enableReceive();
|
||||
void disableReceive();
|
||||
bool available();
|
||||
void resetAvailable();
|
||||
|
||||
unsigned long getReceivedValue();
|
||||
unsigned int getReceivedBitlength();
|
||||
unsigned int getReceivedDelay();
|
||||
unsigned int getReceivedProtocol();
|
||||
unsigned int* getReceivedRawdata();
|
||||
#endif
|
||||
|
||||
void enableTransmit(int nTransmitterPin);
|
||||
void disableTransmit();
|
||||
void setPulseLength(int nPulseLength);
|
||||
void setRepeatTransmit(int nRepeatTransmit);
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
void setReceiveTolerance(int nPercent);
|
||||
#endif
|
||||
void setProtocol(int nProtocol);
|
||||
void setProtocol(int nProtocol, int nPulseLength);
|
||||
|
||||
private:
|
||||
char* getCodeWordB(int nGroupNumber, int nSwitchNumber, boolean bStatus);
|
||||
char* getCodeWordA(char* sGroup, int nSwitchNumber, boolean bStatus);
|
||||
char* getCodeWordA(char* sGroup, char* sDevice, boolean bStatus);
|
||||
char* getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus);
|
||||
char* getCodeWordD(char group, int nDevice, boolean bStatus);
|
||||
void sendT0();
|
||||
void sendT1();
|
||||
void sendTF();
|
||||
void send0();
|
||||
void send1();
|
||||
void sendSync();
|
||||
void transmit(int nHighPulses, int nLowPulses);
|
||||
|
||||
static char* dec2binWzerofill(unsigned long dec, unsigned int length);
|
||||
static char* dec2binWcharfill(unsigned long dec, unsigned int length, char fill);
|
||||
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
static void handleInterrupt();
|
||||
static bool receiveProtocol1(unsigned int changeCount);
|
||||
static bool receiveProtocol2(unsigned int changeCount);
|
||||
static bool receiveProtocol3(unsigned int changeCount);
|
||||
int nReceiverInterrupt;
|
||||
#endif
|
||||
int nTransmitterPin;
|
||||
int nPulseLength;
|
||||
int nRepeatTransmit;
|
||||
char nProtocol;
|
||||
|
||||
#if not defined( RCSwitchDisableReceiving )
|
||||
static int nReceiveTolerance;
|
||||
static unsigned long nReceivedValue;
|
||||
static unsigned int nReceivedBitlength;
|
||||
static unsigned int nReceivedDelay;
|
||||
static unsigned int nReceivedProtocol;
|
||||
#endif
|
||||
/*
|
||||
* timings[0] contains sync timing, followed by a number of bits
|
||||
*/
|
||||
static unsigned int timings[RCSWITCH_MAX_CHANGES];
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Example for receiving
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
|
||||
If you want to visualize a telegram copy the raw data and
|
||||
paste it into http://test.sui.li/oszi/
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (mySwitch.available()) {
|
||||
output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
|
||||
mySwitch.resetAvailable();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength){
|
||||
static char bin[64];
|
||||
unsigned int i=0;
|
||||
|
||||
while (Dec > 0) {
|
||||
bin[32+i++] = (Dec & 1 > 0) ? '1' : '0';
|
||||
Dec = Dec >> 1;
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j< bitLength; j++) {
|
||||
if (j >= bitLength - i) {
|
||||
bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
|
||||
}else {
|
||||
bin[j] = '0';
|
||||
}
|
||||
}
|
||||
bin[bitLength] = '\0';
|
||||
|
||||
return bin;
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw, unsigned int protocol) {
|
||||
|
||||
if (decimal == 0) {
|
||||
Serial.print("Unknown encoding.");
|
||||
} else {
|
||||
char* b = dec2binWzerofill(decimal, length);
|
||||
Serial.print("Decimal: ");
|
||||
Serial.print(decimal);
|
||||
Serial.print(" (");
|
||||
Serial.print( length );
|
||||
Serial.print("Bit) Binary: ");
|
||||
Serial.print( b );
|
||||
Serial.print(" Tri-State: ");
|
||||
Serial.print( bin2tristate( b) );
|
||||
Serial.print(" PulseLength: ");
|
||||
Serial.print(delay);
|
||||
Serial.print(" microseconds");
|
||||
Serial.print(" Protocol: ");
|
||||
Serial.println(protocol);
|
||||
}
|
||||
|
||||
Serial.print("Raw data: ");
|
||||
for (int i=0; i<= length*2; i++) {
|
||||
Serial.print(raw[i]);
|
||||
Serial.print(",");
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
static char* bin2tristate(char* bin) {
|
||||
char returnValue[50];
|
||||
int pos = 0;
|
||||
int pos2 = 0;
|
||||
while (bin[pos]!='\0' && bin[pos+1]!='\0') {
|
||||
if (bin[pos]=='0' && bin[pos+1]=='0') {
|
||||
returnValue[pos2] = '0';
|
||||
} else if (bin[pos]=='1' && bin[pos+1]=='1') {
|
||||
returnValue[pos2] = '1';
|
||||
} else if (bin[pos]=='0' && bin[pos+1]=='1') {
|
||||
returnValue[pos2] = 'F';
|
||||
} else {
|
||||
return "not applicable";
|
||||
}
|
||||
pos = pos+2;
|
||||
pos2++;
|
||||
}
|
||||
returnValue[pos2] = '\0';
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Simple example for receiving
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (mySwitch.available()) {
|
||||
|
||||
int value = mySwitch.getReceivedValue();
|
||||
|
||||
if (value == 0) {
|
||||
Serial.print("Unknown encoding");
|
||||
} else {
|
||||
Serial.print("Received ");
|
||||
Serial.print( mySwitch.getReceivedValue() );
|
||||
Serial.print(" / ");
|
||||
Serial.print( mySwitch.getReceivedBitlength() );
|
||||
Serial.print("bit ");
|
||||
Serial.print("Protocol: ");
|
||||
Serial.println( mySwitch.getReceivedProtocol() );
|
||||
}
|
||||
|
||||
mySwitch.resetAvailable();
|
||||
}
|
||||
}
|
||||
57
libraries/RCSwitch_Tiny/examples/SendDemo/SendDemo.pde
Normal file
57
libraries/RCSwitch_Tiny/examples/SendDemo/SendDemo.pde
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Example for different sending methods
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
// Transmitter is connected to Arduino Pin #10
|
||||
mySwitch.enableTransmit(10);
|
||||
|
||||
// Optional set pulse length.
|
||||
// mySwitch.setPulseLength(320);
|
||||
|
||||
// Optional set protocol (default is 1, will work for most outlets)
|
||||
// mySwitch.setProtocol(2);
|
||||
|
||||
// Optional set number of transmission repetitions.
|
||||
// mySwitch.setRepeatTransmit(15);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
/* See Example: TypeA_WithDIPSwitches */
|
||||
mySwitch.switchOn("11111", "00010");
|
||||
delay(1000);
|
||||
mySwitch.switchOn("11111", "00010");
|
||||
delay(1000);
|
||||
|
||||
/* Same switch as above, but using decimal code */
|
||||
mySwitch.send(5393, 24);
|
||||
delay(1000);
|
||||
mySwitch.send(5396, 24);
|
||||
delay(1000);
|
||||
|
||||
/* Same switch as above, but using binary code */
|
||||
mySwitch.send("000000000001010100010001");
|
||||
delay(1000);
|
||||
mySwitch.send("000000000001010100010100");
|
||||
delay(1000);
|
||||
|
||||
/* Same switch as above, but tri-state code */
|
||||
mySwitch.sendTriState("00000FFF0F0F");
|
||||
delay(1000);
|
||||
mySwitch.sendTriState("00000FFF0FF0");
|
||||
delay(1000);
|
||||
|
||||
delay(20000);
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Example for outlets which are configured with a 10 pole DIP switch.
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
|
||||
// Transmitter is connected to Arduino Pin #10
|
||||
mySwitch.enableTransmit(10);
|
||||
|
||||
// Optional set pulse length.
|
||||
// mySwitch.setPulseLength(320);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Switch on:
|
||||
// The first parameter represents the setting of the first 5 DIP switches.
|
||||
// In this example it's ON-ON-OFF-OFF-ON.
|
||||
//
|
||||
// The second parameter represents the setting of the last 5 DIP switches.
|
||||
// In this example the last 5 DIP switches are OFF-ON-OFF-ON-OFF.
|
||||
mySwitch.switchOn("11001", "01010");
|
||||
|
||||
// Wait a second
|
||||
delay(1000);
|
||||
|
||||
// Switch off
|
||||
mySwitch.switchOff("11001", "01010");
|
||||
|
||||
// Wait another second
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
This is a minimal sketch without using the library at all but only works for
|
||||
the 10 pole dip switch sockets. It saves a lot of memory and thus might be
|
||||
very useful to use with ATTinys :)
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
*/
|
||||
|
||||
int RCLpin = 7;
|
||||
|
||||
void setup() {
|
||||
pinMode(RCLpin, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
RCLswitch(0b010001000001); // DIPs an Steckdose: 0100010000 An:01
|
||||
delay(2000);
|
||||
|
||||
RCLswitch(0b010001000010); // DIPs an Steckdose: 0100010000 Aus:10
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
void RCLswitch(uint16_t code) {
|
||||
for (int nRepeat=0; nRepeat<6; nRepeat++) {
|
||||
for (int i=4; i<16; i++) {
|
||||
RCLtransmit(1,3);
|
||||
if (((code << (i-4)) & 2048) > 0) {
|
||||
RCLtransmit(1,3);
|
||||
} else {
|
||||
RCLtransmit(3,1);
|
||||
}
|
||||
}
|
||||
RCLtransmit(1,31);
|
||||
}
|
||||
}
|
||||
|
||||
void RCLtransmit(int nHighPulses, int nLowPulses) {
|
||||
digitalWrite(RCLpin, HIGH);
|
||||
delayMicroseconds( 350 * nHighPulses);
|
||||
digitalWrite(RCLpin, LOW);
|
||||
delayMicroseconds( 350 * nLowPulses);
|
||||
}
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Example for outlets which are configured with two rotary/sliding switches.
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
|
||||
// Transmitter is connected to Arduino Pin #10
|
||||
mySwitch.enableTransmit(10);
|
||||
|
||||
// Optional set pulse length.
|
||||
// mySwitch.setPulseLength(320);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Switch on:
|
||||
// The first parameter represents the setting of the first rotary switch.
|
||||
// In this example it's switched to "1" or "A" or "I".
|
||||
//
|
||||
// The second parameter represents the setting of the second rotary switch.
|
||||
// In this example it's switched to "4" or "D" or "IV".
|
||||
mySwitch.switchOn(1, 4);
|
||||
|
||||
// Wait a second
|
||||
delay(1000);
|
||||
|
||||
// Switch off
|
||||
mySwitch.switchOff(1, 4);
|
||||
|
||||
// Wait another second
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Example for Intertechno outlets
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
|
||||
// Transmitter is connected to Arduino Pin #10
|
||||
mySwitch.enableTransmit(10);
|
||||
|
||||
// Optional set pulse length.
|
||||
// mySwitch.setPulseLength(320);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Switch on:
|
||||
// The first parameter represents the familycode (a, b, c, ... f)
|
||||
// The second parameter represents the group number
|
||||
// The third parameter represents the device number
|
||||
//
|
||||
// In this example it's family 'b', group #3, device #2
|
||||
mySwitch.switchOn('b', 3, 2);
|
||||
|
||||
// Wait a second
|
||||
delay(1000);
|
||||
|
||||
// Switch off
|
||||
mySwitch.switchOff('b', 3, 2);
|
||||
|
||||
// Wait another second
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
41
libraries/RCSwitch_Tiny/examples/TypeD_REV/TypeD_REV.ino
Normal file
41
libraries/RCSwitch_Tiny/examples/TypeD_REV/TypeD_REV.ino
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Example for REV outlets (e.g. 8342L)
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
|
||||
Need help? http://forum.ardumote.com
|
||||
*/
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setup() {
|
||||
|
||||
// Transmitter is connected to Arduino Pin #10
|
||||
mySwitch.enableTransmit(10);
|
||||
|
||||
// set pulse length.
|
||||
mySwitch.setPulseLength(360);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Switch on:
|
||||
// The first parameter represents the channel (a, b, c, d)
|
||||
// The second parameter represents the device number
|
||||
//
|
||||
// In this example it's family 'd', device #2
|
||||
mySwitch.switchOn('d', 2);
|
||||
|
||||
// Wait a second
|
||||
delay(1000);
|
||||
|
||||
// Switch off
|
||||
mySwitch.switchOff('d', 2);
|
||||
|
||||
// Wait another second
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
154
libraries/RCSwitch_Tiny/examples/Webserver/Webserver.pde
Normal file
154
libraries/RCSwitch_Tiny/examples/Webserver/Webserver.pde
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
A simple RCSwitch/Ethernet/Webserver demo
|
||||
|
||||
http://code.google.com/p/rc-switch/
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
#include <RCSwitch.h>
|
||||
|
||||
// Ethernet configuration
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC Address
|
||||
byte ip[] = { 192,168,0, 2 }; // IP Address
|
||||
EthernetServer server(80); // Server Port 80
|
||||
|
||||
// RCSwitch configuration
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
int RCTransmissionPin = 7;
|
||||
|
||||
// More to do...
|
||||
// You should also modify the processCommand() and
|
||||
// httpResponseHome() functions to fit your needs.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Setup
|
||||
*/
|
||||
void setup() {
|
||||
Ethernet.begin(mac, ip);
|
||||
server.begin();
|
||||
mySwitch.enableTransmit( RCTransmissionPin );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop
|
||||
*/
|
||||
void loop() {
|
||||
char* command = httpServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Command dispatcher
|
||||
*/
|
||||
void processCommand(char* command) {
|
||||
if (strcmp(command, "1-on") == 0) {
|
||||
mySwitch.switchOn(1,1);
|
||||
} else if (strcmp(command, "1-off") == 0) {
|
||||
mySwitch.switchOff(1,1);
|
||||
} else if (strcmp(command, "2-on") == 0) {
|
||||
mySwitch.switchOn(1,2);
|
||||
} else if (strcmp(command, "2-off") == 0) {
|
||||
mySwitch.switchOff(1,2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Response with homepage
|
||||
*/
|
||||
void httpResponseHome(EthernetClient c) {
|
||||
c.println("HTTP/1.1 200 OK");
|
||||
c.println("Content-Type: text/html");
|
||||
c.println();
|
||||
c.println("<html>");
|
||||
c.println("<head>");
|
||||
c.println( "<title>RCSwitch Webserver Demo</title>");
|
||||
c.println( "<style>");
|
||||
c.println( "body { font-family: Arial, sans-serif; font-size:12px; }");
|
||||
c.println( "</style>");
|
||||
c.println("</head>");
|
||||
c.println("<body>");
|
||||
c.println( "<h1>RCSwitch Webserver Demo</h1>");
|
||||
c.println( "<ul>");
|
||||
c.println( "<li><a href=\"./?1-on\">Switch #1 on</a></li>");
|
||||
c.println( "<li><a href=\"./?1-off\">Switch #1 off</a></li>");
|
||||
c.println( "</ul>");
|
||||
c.println( "<ul>");
|
||||
c.println( "<li><a href=\"./?2-on\">Switch #2 on</a></li>");
|
||||
c.println( "<li><a href=\"./?2-off\">Switch #2 off</a></li>");
|
||||
c.println( "</ul>");
|
||||
c.println( "<hr>");
|
||||
c.println( "<a href=\"http://code.google.com/p/rc-switch/\">http://code.google.com/p/rc-switch/</a>");
|
||||
c.println("</body>");
|
||||
c.println("</html>");
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Redirect to homepage
|
||||
*/
|
||||
void httpResponseRedirect(EthernetClient c) {
|
||||
c.println("HTTP/1.1 301 Found");
|
||||
c.println("Location: /");
|
||||
c.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Response 414 error
|
||||
* Command must not be longer than 30 characters
|
||||
**/
|
||||
void httpResponse414(EthernetClient c) {
|
||||
c.println("HTTP/1.1 414 Request URI too long");
|
||||
c.println("Content-Type: text/plain");
|
||||
c.println();
|
||||
c.println("414 Request URI too long");
|
||||
}
|
||||
|
||||
/**
|
||||
* Process HTTP requests, parse first request header line and
|
||||
* call processCommand with GET query string (everything after
|
||||
* the ? question mark in the URL).
|
||||
*/
|
||||
char* httpServer() {
|
||||
EthernetClient client = server.available();
|
||||
if (client) {
|
||||
char sReturnCommand[32];
|
||||
int nCommandPos=-1;
|
||||
sReturnCommand[0] = '\0';
|
||||
while (client.connected()) {
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
if ((c == '\n') || (c == ' ' && nCommandPos>-1)) {
|
||||
sReturnCommand[nCommandPos] = '\0';
|
||||
if (strcmp(sReturnCommand, "\0") == 0) {
|
||||
httpResponseHome(client);
|
||||
} else {
|
||||
processCommand(sReturnCommand);
|
||||
httpResponseRedirect(client);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (nCommandPos>-1) {
|
||||
sReturnCommand[nCommandPos++] = c;
|
||||
}
|
||||
if (c == '?' && nCommandPos == -1) {
|
||||
nCommandPos = 0;
|
||||
}
|
||||
}
|
||||
if (nCommandPos > 30) {
|
||||
httpResponse414(client);
|
||||
sReturnCommand[0] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nCommandPos!=-1) {
|
||||
sReturnCommand[nCommandPos] = '\0';
|
||||
}
|
||||
// give the web browser time to receive the data
|
||||
delay(1);
|
||||
client.stop();
|
||||
|
||||
return sReturnCommand;
|
||||
}
|
||||
return '\0';
|
||||
}
|
||||
57
libraries/RCSwitch_Tiny/keywords.txt
Normal file
57
libraries/RCSwitch_Tiny/keywords.txt
Normal file
@ -0,0 +1,57 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For RCSwitch
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
RCSwitch KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
##########
|
||||
#SENDS Begin
|
||||
##########
|
||||
switchOn KEYWORD2
|
||||
switchOff KEYWORD2
|
||||
sendTriState KEYWORD2
|
||||
send KEYWORD2
|
||||
##########
|
||||
#SENDS End
|
||||
##########
|
||||
|
||||
##########
|
||||
#RECEIVE Begin
|
||||
##########
|
||||
enableReceive KEYWORD2
|
||||
disableReceive KEYWORD2
|
||||
available KEYWORD2
|
||||
resetAvailable KEYWORD2
|
||||
setReceiveTolerance KEYWORD2
|
||||
getReceivedValue KEYWORD2
|
||||
getReceivedBitlength KEYWORD2
|
||||
getReceivedDelay KEYWORD2
|
||||
getReceivedProtocol KEYWORD2
|
||||
getReceivedRawdata KEYWORD2
|
||||
##########
|
||||
#RECEIVE End
|
||||
##########
|
||||
|
||||
##########
|
||||
#OTHERS Begin
|
||||
##########
|
||||
enableTransmit KEYWORD2
|
||||
disableTransmit KEYWORD2
|
||||
setPulseLength KEYWORD2
|
||||
setProtocol KEYWORD2
|
||||
setRepeatTransmit KEYWORD2
|
||||
##########
|
||||
#OTHERS End
|
||||
##########
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
489
libraries/SoftwareSerial_Tiny/SoftwareSerial_Tiny.cpp
Normal file
489
libraries/SoftwareSerial_Tiny/SoftwareSerial_Tiny.cpp
Normal file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
|
||||
Multi-instance software serial library for Arduino/Wiring
|
||||
-- Interrupt-driven receive and other improvements by ladyada
|
||||
(http://ladyada.net)
|
||||
-- Tuning, circular buffer, derivation from class Print/Stream,
|
||||
multi-instance support, porting to 8MHz processors,
|
||||
various optimizations, PROGMEM delay tables, inverse logic and
|
||||
direct port writing by Mikal Hart (http://www.arduiniana.org)
|
||||
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
|
||||
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
|
||||
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
|
||||
|
||||
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
|
||||
|
||||
The latest version of this library can always be found at
|
||||
http://arduiniana.org.
|
||||
*/
|
||||
|
||||
// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
|
||||
// oscilloscope or logic analyzer. Beware: it also slightly modifies
|
||||
// the bit times, so don't rely on it too much at high baud rates
|
||||
#define _DEBUG 0
|
||||
#define _DEBUG_PIN1 11
|
||||
#define _DEBUG_PIN2 13
|
||||
//
|
||||
// Includes
|
||||
//
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <Arduino.h>
|
||||
#include <SoftwareSerial_Tiny.h>
|
||||
#include <util/delay_basic.h>
|
||||
|
||||
//
|
||||
// Statics
|
||||
//
|
||||
SoftwareSerial *SoftwareSerial::active_object = 0;
|
||||
char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
|
||||
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
|
||||
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
|
||||
|
||||
//
|
||||
// Debugging
|
||||
//
|
||||
// This function generates a brief pulse
|
||||
// for debugging or measuring on an oscilloscope.
|
||||
inline void DebugPulse(uint8_t pin, uint8_t count)
|
||||
{
|
||||
#if _DEBUG
|
||||
volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
|
||||
|
||||
uint8_t val = *pport;
|
||||
while (count--)
|
||||
{
|
||||
*pport = val | digitalPinToBitMask(pin);
|
||||
*pport = val;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
|
||||
/* static */
|
||||
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
|
||||
_delay_loop_2(delay);
|
||||
}
|
||||
|
||||
// This function sets the current object as the "listening"
|
||||
// one and returns true if it replaces another
|
||||
bool SoftwareSerial::listen()
|
||||
{
|
||||
if (!_rx_delay_stopbit)
|
||||
return false;
|
||||
|
||||
if (active_object != this)
|
||||
{
|
||||
if (active_object)
|
||||
active_object->stopListening();
|
||||
|
||||
_buffer_overflow = false;
|
||||
_receive_buffer_head = _receive_buffer_tail = 0;
|
||||
active_object = this;
|
||||
|
||||
setRxIntMsk(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stop listening. Returns true if we were actually listening.
|
||||
bool SoftwareSerial::stopListening()
|
||||
{
|
||||
if (active_object == this)
|
||||
{
|
||||
setRxIntMsk(false);
|
||||
active_object = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// The receive routine called by the interrupt handler
|
||||
//
|
||||
void SoftwareSerial::recv()
|
||||
{
|
||||
|
||||
#if GCC_VERSION < 40302
|
||||
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||
// Preserve the registers that the compiler misses
|
||||
// (courtesy of Arduino forum user *etracer*)
|
||||
asm volatile(
|
||||
"push r18 \n\t"
|
||||
"push r19 \n\t"
|
||||
"push r20 \n\t"
|
||||
"push r21 \n\t"
|
||||
"push r22 \n\t"
|
||||
"push r23 \n\t"
|
||||
"push r26 \n\t"
|
||||
"push r27 \n\t"
|
||||
::);
|
||||
#endif
|
||||
|
||||
uint8_t d = 0;
|
||||
|
||||
// If RX line is high, then we don't see any start bit
|
||||
// so interrupt is probably not for us
|
||||
if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
|
||||
{
|
||||
// Disable further interrupts during reception, this prevents
|
||||
// triggering another interrupt directly after we return, which can
|
||||
// cause problems at higher baudrates.
|
||||
setRxIntMsk(false);
|
||||
|
||||
// Wait approximately 1/2 of a bit width to "center" the sample
|
||||
tunedDelay(_rx_delay_centering);
|
||||
DebugPulse(_DEBUG_PIN2, 1);
|
||||
|
||||
// Read each of the 8 bits
|
||||
for (uint8_t i=8; i > 0; --i)
|
||||
{
|
||||
tunedDelay(_rx_delay_intrabit);
|
||||
d >>= 1;
|
||||
DebugPulse(_DEBUG_PIN2, 1);
|
||||
if (rx_pin_read())
|
||||
d |= 0x80;
|
||||
}
|
||||
|
||||
if (_inverse_logic)
|
||||
d = ~d;
|
||||
|
||||
// if buffer full, set the overflow flag and return
|
||||
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
|
||||
if (next != _receive_buffer_head)
|
||||
{
|
||||
// save new data in buffer: tail points to where byte goes
|
||||
_receive_buffer[_receive_buffer_tail] = d; // save new byte
|
||||
_receive_buffer_tail = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugPulse(_DEBUG_PIN1, 1);
|
||||
_buffer_overflow = true;
|
||||
}
|
||||
|
||||
// skip the stop bit
|
||||
tunedDelay(_rx_delay_stopbit);
|
||||
DebugPulse(_DEBUG_PIN1, 1);
|
||||
|
||||
// Re-enable interrupts when we're sure to be inside the stop bit
|
||||
setRxIntMsk(true);
|
||||
|
||||
}
|
||||
|
||||
#if GCC_VERSION < 40302
|
||||
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||
// Restore the registers that the compiler misses
|
||||
asm volatile(
|
||||
"pop r27 \n\t"
|
||||
"pop r26 \n\t"
|
||||
"pop r23 \n\t"
|
||||
"pop r22 \n\t"
|
||||
"pop r21 \n\t"
|
||||
"pop r20 \n\t"
|
||||
"pop r19 \n\t"
|
||||
"pop r18 \n\t"
|
||||
::);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t SoftwareSerial::rx_pin_read()
|
||||
{
|
||||
return *_receivePortRegister & _receiveBitMask;
|
||||
}
|
||||
|
||||
//
|
||||
// Interrupt handling
|
||||
//
|
||||
|
||||
/* static */
|
||||
inline void SoftwareSerial::handle_interrupt()
|
||||
{
|
||||
if (active_object)
|
||||
{
|
||||
active_object->recv();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PCINT0_vect)
|
||||
//ISR(PCINT0_vect) {
|
||||
// SoftwareSerial::handle_interrupt();
|
||||
//}
|
||||
#endif
|
||||
|
||||
#if defined(PCINT1_vect)
|
||||
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
|
||||
#endif
|
||||
|
||||
#if defined(PCINT2_vect)
|
||||
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
|
||||
#endif
|
||||
|
||||
#if defined(PCINT3_vect)
|
||||
ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
|
||||
_rx_delay_centering(0),
|
||||
_rx_delay_intrabit(0),
|
||||
_rx_delay_stopbit(0),
|
||||
_tx_delay(0),
|
||||
_buffer_overflow(false),
|
||||
_inverse_logic(inverse_logic)
|
||||
{
|
||||
setTX(transmitPin);
|
||||
setRX(receivePin);
|
||||
}
|
||||
|
||||
//
|
||||
// Destructor
|
||||
//
|
||||
SoftwareSerial::~SoftwareSerial()
|
||||
{
|
||||
end();
|
||||
}
|
||||
|
||||
void SoftwareSerial::setTX(uint8_t tx)
|
||||
{
|
||||
// First write, then set output. If we do this the other way around,
|
||||
// the pin would be output low for a short while before switching to
|
||||
// output hihg. Now, it is input with pullup for a short while, which
|
||||
// is fine. With inverse logic, either order is fine.
|
||||
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
|
||||
pinMode(tx, OUTPUT);
|
||||
_transmitBitMask = digitalPinToBitMask(tx);
|
||||
uint8_t port = digitalPinToPort(tx);
|
||||
_transmitPortRegister = portOutputRegister(port);
|
||||
}
|
||||
|
||||
void SoftwareSerial::setRX(uint8_t rx)
|
||||
{
|
||||
pinMode(rx, INPUT);
|
||||
if (!_inverse_logic)
|
||||
digitalWrite(rx, HIGH); // pullup for normal logic!
|
||||
_receivePin = rx;
|
||||
_receiveBitMask = digitalPinToBitMask(rx);
|
||||
uint8_t port = digitalPinToPort(rx);
|
||||
_receivePortRegister = portInputRegister(port);
|
||||
}
|
||||
|
||||
uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) {
|
||||
if (num > sub)
|
||||
return num - sub;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
void SoftwareSerial::begin(long speed)
|
||||
{
|
||||
_rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
|
||||
|
||||
// Precalculate the various delays, in number of 4-cycle delays
|
||||
uint16_t bit_delay = (F_CPU / speed) / 4;
|
||||
|
||||
// 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit,
|
||||
// 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits,
|
||||
// 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit
|
||||
// These are all close enough to just use 15 cycles, since the inter-bit
|
||||
// timings are the most critical (deviations stack 8 times)
|
||||
_tx_delay = subtract_cap(bit_delay, 15 / 4);
|
||||
|
||||
// Only setup rx when we have a valid PCINT for this pin
|
||||
if (digitalPinToPCICR(_receivePin)) {
|
||||
#if GCC_VERSION > 40800
|
||||
// Timings counted from gcc 4.8.2 output. This works up to 115200 on
|
||||
// 16Mhz and 57600 on 8Mhz.
|
||||
//
|
||||
// When the start bit occurs, there are 3 or 4 cycles before the
|
||||
// interrupt flag is set, 4 cycles before the PC is set to the right
|
||||
// interrupt vector address and the old PC is pushed on the stack,
|
||||
// and then 75 cycles of instructions (including the RJMP in the
|
||||
// ISR vector table) until the first delay. After the delay, there
|
||||
// are 17 more cycles until the pin value is read (excluding the
|
||||
// delay in the loop).
|
||||
// We want to have a total delay of 1.5 bit time. Inside the loop,
|
||||
// we already wait for 1 bit time - 23 cycles, so here we wait for
|
||||
// 0.5 bit time - (71 + 18 - 22) cycles.
|
||||
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
|
||||
|
||||
// There are 23 cycles in each loop iteration (excluding the delay)
|
||||
_rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
|
||||
|
||||
// There are 37 cycles from the last bit read to the start of
|
||||
// stopbit delay and 11 cycles from the delay until the interrupt
|
||||
// mask is enabled again (which _must_ happen during the stopbit).
|
||||
// This delay aims at 3/4 of a bit time, meaning the end of the
|
||||
// delay will be at 1/4th of the stopbit. This allows some extra
|
||||
// time for ISR cleanup, which makes 115200 baud at 16Mhz work more
|
||||
// reliably
|
||||
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
|
||||
#else // Timings counted from gcc 4.3.2 output
|
||||
// Note that this code is a _lot_ slower, mostly due to bad register
|
||||
// allocation choices of gcc. This works up to 57600 on 16Mhz and
|
||||
// 38400 on 8Mhz.
|
||||
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4);
|
||||
_rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4);
|
||||
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4);
|
||||
#endif
|
||||
|
||||
|
||||
// Enable the PCINT for the entire port here, but never disable it
|
||||
// (others might also need it, so we disable the interrupt by using
|
||||
// the per-pin PCMSK register).
|
||||
*digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
|
||||
// Precalculate the pcint mask register and value, so setRxIntMask
|
||||
// can be used inside the ISR without costing too much time.
|
||||
_pcint_maskreg = digitalPinToPCMSK(_receivePin);
|
||||
_pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin));
|
||||
|
||||
tunedDelay(_tx_delay); // if we were low this establishes the end
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
pinMode(_DEBUG_PIN1, OUTPUT);
|
||||
pinMode(_DEBUG_PIN2, OUTPUT);
|
||||
#endif
|
||||
|
||||
listen();
|
||||
}
|
||||
|
||||
void SoftwareSerial::setRxIntMsk(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
*_pcint_maskreg |= _pcint_maskvalue;
|
||||
else
|
||||
*_pcint_maskreg &= ~_pcint_maskvalue;
|
||||
}
|
||||
|
||||
void SoftwareSerial::end()
|
||||
{
|
||||
stopListening();
|
||||
}
|
||||
|
||||
|
||||
// Read data from buffer
|
||||
int SoftwareSerial::read()
|
||||
{
|
||||
if (!isListening())
|
||||
return -1;
|
||||
|
||||
// Empty buffer?
|
||||
if (_receive_buffer_head == _receive_buffer_tail)
|
||||
return -1;
|
||||
|
||||
// Read from "head"
|
||||
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
|
||||
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
|
||||
return d;
|
||||
}
|
||||
|
||||
int SoftwareSerial::available()
|
||||
{
|
||||
if (!isListening())
|
||||
return 0;
|
||||
|
||||
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
|
||||
}
|
||||
|
||||
size_t SoftwareSerial::write(uint8_t b)
|
||||
{
|
||||
if (_tx_delay == 0) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// By declaring these as local variables, the compiler will put them
|
||||
// in registers _before_ disabling interrupts and entering the
|
||||
// critical timing sections below, which makes it a lot easier to
|
||||
// verify the cycle timings
|
||||
volatile uint8_t *reg = _transmitPortRegister;
|
||||
uint8_t reg_mask = _transmitBitMask;
|
||||
uint8_t inv_mask = ~_transmitBitMask;
|
||||
uint8_t oldSREG = SREG;
|
||||
bool inv = _inverse_logic;
|
||||
uint16_t delay = _tx_delay;
|
||||
|
||||
if (inv)
|
||||
b = ~b;
|
||||
|
||||
cli(); // turn off interrupts for a clean txmit
|
||||
|
||||
// Write the start bit
|
||||
if (inv)
|
||||
*reg |= reg_mask;
|
||||
else
|
||||
*reg &= inv_mask;
|
||||
|
||||
tunedDelay(delay);
|
||||
|
||||
// Write each of the 8 bits
|
||||
for (uint8_t i = 8; i > 0; --i)
|
||||
{
|
||||
if (b & 1) // choose bit
|
||||
*reg |= reg_mask; // send 1
|
||||
else
|
||||
*reg &= inv_mask; // send 0
|
||||
|
||||
tunedDelay(delay);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
// restore pin to natural state
|
||||
if (inv)
|
||||
*reg &= inv_mask;
|
||||
else
|
||||
*reg |= reg_mask;
|
||||
|
||||
SREG = oldSREG; // turn interrupts back on
|
||||
tunedDelay(_tx_delay);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SoftwareSerial::flush()
|
||||
{
|
||||
if (!isListening())
|
||||
return;
|
||||
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
_receive_buffer_head = _receive_buffer_tail = 0;
|
||||
SREG = oldSREG;
|
||||
}
|
||||
|
||||
int SoftwareSerial::peek()
|
||||
{
|
||||
if (!isListening())
|
||||
return -1;
|
||||
|
||||
// Empty buffer?
|
||||
if (_receive_buffer_head == _receive_buffer_tail)
|
||||
return -1;
|
||||
|
||||
// Read from "head"
|
||||
return _receive_buffer[_receive_buffer_head];
|
||||
}
|
||||
121
libraries/SoftwareSerial_Tiny/SoftwareSerial_Tiny.h
Normal file
121
libraries/SoftwareSerial_Tiny/SoftwareSerial_Tiny.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
SoftwareSerial.h (formerly NewSoftSerial.h) -
|
||||
Multi-instance software serial library for Arduino/Wiring
|
||||
-- Interrupt-driven receive and other improvements by ladyada
|
||||
(http://ladyada.net)
|
||||
-- Tuning, circular buffer, derivation from class Print/Stream,
|
||||
multi-instance support, porting to 8MHz processors,
|
||||
various optimizations, PROGMEM delay tables, inverse logic and
|
||||
direct port writing by Mikal Hart (http://www.arduiniana.org)
|
||||
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
|
||||
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
|
||||
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
|
||||
|
||||
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
|
||||
|
||||
The latest version of this library can always be found at
|
||||
http://arduiniana.org.
|
||||
*/
|
||||
|
||||
#ifndef SoftwareSerial_h
|
||||
#define SoftwareSerial_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <Stream.h>
|
||||
|
||||
/******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define _SS_MAX_RX_BUFF 64 // RX buffer size
|
||||
#ifndef GCC_VERSION
|
||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#endif
|
||||
|
||||
class SoftwareSerial : public Stream
|
||||
{
|
||||
private:
|
||||
// per object data
|
||||
uint8_t _receivePin;
|
||||
uint8_t _receiveBitMask;
|
||||
volatile uint8_t *_receivePortRegister;
|
||||
uint8_t _transmitBitMask;
|
||||
volatile uint8_t *_transmitPortRegister;
|
||||
volatile uint8_t *_pcint_maskreg;
|
||||
uint8_t _pcint_maskvalue;
|
||||
|
||||
// Expressed as 4-cycle delays (must never be 0!)
|
||||
uint16_t _rx_delay_centering;
|
||||
uint16_t _rx_delay_intrabit;
|
||||
uint16_t _rx_delay_stopbit;
|
||||
uint16_t _tx_delay;
|
||||
|
||||
uint16_t _buffer_overflow:1;
|
||||
uint16_t _inverse_logic:1;
|
||||
|
||||
// static data
|
||||
static char _receive_buffer[_SS_MAX_RX_BUFF];
|
||||
static volatile uint8_t _receive_buffer_tail;
|
||||
static volatile uint8_t _receive_buffer_head;
|
||||
static SoftwareSerial *active_object;
|
||||
|
||||
// private methods
|
||||
void recv() __attribute__((__always_inline__));
|
||||
uint8_t rx_pin_read();
|
||||
void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__));
|
||||
void setTX(uint8_t transmitPin);
|
||||
void setRX(uint8_t receivePin);
|
||||
void setRxIntMsk(bool enable) __attribute__((__always_inline__));
|
||||
|
||||
// Return num - sub, or 1 if the result would be < 1
|
||||
static uint16_t subtract_cap(uint16_t num, uint16_t sub);
|
||||
|
||||
// private static method for timing
|
||||
static inline void tunedDelay(uint16_t delay);
|
||||
|
||||
public:
|
||||
// public methods
|
||||
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
|
||||
~SoftwareSerial();
|
||||
void begin(long speed);
|
||||
bool listen();
|
||||
void end();
|
||||
bool isListening() { return this == active_object; }
|
||||
bool stopListening();
|
||||
bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; }
|
||||
int peek();
|
||||
|
||||
virtual size_t write(uint8_t byte);
|
||||
virtual int read();
|
||||
virtual int available();
|
||||
virtual void flush();
|
||||
operator bool() { return true; }
|
||||
|
||||
using Print::write;
|
||||
|
||||
// public only for easy access by interrupt handlers
|
||||
static inline void handle_interrupt() __attribute__((__always_inline__));
|
||||
};
|
||||
|
||||
// Arduino 0012 workaround
|
||||
#undef int
|
||||
#undef char
|
||||
#undef long
|
||||
#undef byte
|
||||
#undef float
|
||||
#undef abs
|
||||
#undef round
|
||||
|
||||
#endif
|
||||
30
libraries/SoftwareSerial_Tiny/keywords.txt
Normal file
30
libraries/SoftwareSerial_Tiny/keywords.txt
Normal file
@ -0,0 +1,30 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map for SoftwareSerial
|
||||
# (formerly NewSoftSerial)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
SoftwareSerial KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
end KEYWORD2
|
||||
read KEYWORD2
|
||||
write KEYWORD2
|
||||
available KEYWORD2
|
||||
isListening KEYWORD2
|
||||
overflow KEYWORD2
|
||||
flush KEYWORD2
|
||||
listen KEYWORD2
|
||||
peek KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
9
libraries/SoftwareSerial_Tiny/library.properties
Normal file
9
libraries/SoftwareSerial_Tiny/library.properties
Normal file
@ -0,0 +1,9 @@
|
||||
name=SoftwareSerial_Tiny
|
||||
version=1.0
|
||||
author=Arduino
|
||||
maintainer=Arduino <info@arduino.cc>
|
||||
sentence=Enables serial communication on digital pins. For all Arduino boards, BUT Arduino DUE.
|
||||
paragraph=
|
||||
url=http://www.arduino.cc/en/Reference/SoftwareSerial
|
||||
architectures=avr
|
||||
|
||||
51
libraries/TinyPower/TinyPower.h
Normal file
51
libraries/TinyPower/TinyPower.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
// Utility macros
|
||||
#define adc_disable() (ADCSRA &= ~_BV(ADEN)) // disable ADC (before power-off)
|
||||
#define adc_enable() (ADCSRA |= _BV(ADEN)) // re-enable ADC
|
||||
#define enable_pin_interrupts() (GIMSK |= _BV(PCIE)) // Enable Pin Change Interrupts
|
||||
|
||||
class TinyPower {
|
||||
|
||||
public:
|
||||
static void setup() {
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
enable_pin_interrupts();
|
||||
enableWdt();
|
||||
}
|
||||
|
||||
static void sleep() {
|
||||
PCMSK |= _BV(PCINT0); // Use PB0 as interrupt pin
|
||||
adc_disable();
|
||||
|
||||
sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
|
||||
sei(); // Enable interrupts
|
||||
|
||||
sleep_cpu(); // sleep
|
||||
|
||||
cli(); // Disable interrupts
|
||||
PCMSK &= ~_BV(PCINT0); // Turn off PB0 as interrupt pin
|
||||
sleep_disable(); // Clear SE bit
|
||||
adc_enable();
|
||||
|
||||
sei(); // Enable interrupts
|
||||
}
|
||||
|
||||
//enable the wdt for 8sec interrupt
|
||||
static void enableWdt()
|
||||
{
|
||||
MCUSR = 0x00;
|
||||
WDTCR |= _BV(WDCE) | _BV(WDE);
|
||||
WDTCR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0); //8192ms
|
||||
}
|
||||
|
||||
static void disableWdt() {
|
||||
MCUSR = 0x00;
|
||||
WDTCR |= _BV(WDCE) | _BV(WDE);
|
||||
WDTCR = 0x00;
|
||||
}
|
||||
};
|
||||
55
libraries/TinySensor/TinySensor.h
Normal file
55
libraries/TinySensor/TinySensor.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
class TinySensor {
|
||||
short id;
|
||||
short senderPin;
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
public:
|
||||
TinySensor(short id, short senderPin) {
|
||||
this->id = id;
|
||||
this->senderPin = senderPin;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
mySwitch.enableTransmit(senderPin);
|
||||
mySwitch.setProtocol(2);
|
||||
}
|
||||
|
||||
void sendWindowState(bool state) {
|
||||
unsigned long value = 0x70000000;
|
||||
value |= readVcc() << 6;
|
||||
value |= !state << 5;
|
||||
value |= id;
|
||||
mySwitch.send(value, 32);
|
||||
}
|
||||
|
||||
long readVcc() {
|
||||
// Read 1.1V reference against AVcc
|
||||
// set the reference to Vcc and the measurement to the internal 1.1V reference
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
|
||||
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
ADMUX = _BV(MUX5) | _BV(MUX0);
|
||||
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
ADMUX = _BV(MUX3) | _BV(MUX2);
|
||||
#else
|
||||
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
|
||||
#endif
|
||||
|
||||
delay(2); // Wait for Vref to settle
|
||||
ADCSRA |= _BV(ADSC); // Start conversion
|
||||
while (bit_is_set(ADCSRA, ADSC))
|
||||
; // measuring
|
||||
|
||||
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
|
||||
uint8_t high = ADCH; // unlocks both
|
||||
|
||||
long result = (high << 8) | low;
|
||||
|
||||
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
|
||||
return result; // Vcc in millivolts
|
||||
}
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user