RS485 transport layer
Note this is still untested as I haven't got any RS485 modules.
This commit is contained in:
@@ -53,11 +53,11 @@
|
|||||||
* Radio selection and node config
|
* Radio selection and node config
|
||||||
***********************************/
|
***********************************/
|
||||||
|
|
||||||
// Selecting radio transport is optional (for a gateway node).
|
// Selecting uplink transport layer is optional (for a gateway node).
|
||||||
|
|
||||||
//#define MY_RADIO_NRF24
|
//#define MY_RADIO_NRF24
|
||||||
//#define MY_RADIO_RFM69
|
//#define MY_RADIO_RFM69
|
||||||
|
//#define MY_RS485
|
||||||
|
|
||||||
// Node id defaults to AUTO (tries to fetch id from controller)
|
// Node id defaults to AUTO (tries to fetch id from controller)
|
||||||
#ifndef MY_NODE_ID
|
#ifndef MY_NODE_ID
|
||||||
@@ -233,6 +233,18 @@
|
|||||||
#define MY_SIGNING_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
#define MY_SIGNING_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* RS485 Driver Defaults
|
||||||
|
***********************************/
|
||||||
|
|
||||||
|
#ifndef MY_RS485_BAUD_RATE
|
||||||
|
#define MY_RS485_BAUD_RATE 9600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MY_RS485_MAX_MESSAGE_LENGTH
|
||||||
|
#define MY_RS485_MAX_MESSAGE_LENGTH 40
|
||||||
|
#endif
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* NRF24L01 Driver Defaults
|
* NRF24L01 Driver Defaults
|
||||||
***********************************/
|
***********************************/
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable radio "feature" if one of the radio types was enabled
|
// Enable radio "feature" if one of the radio types was enabled
|
||||||
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69)
|
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69) || defined(MY_RS485)
|
||||||
#define MY_RADIO_FEATURE
|
#define MY_RADIO_FEATURE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// RADIO
|
// RADIO
|
||||||
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69)
|
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69) || defined(MY_RS485)
|
||||||
// SOFTSPI
|
// SOFTSPI
|
||||||
#ifdef MY_SOFTSPI
|
#ifdef MY_SOFTSPI
|
||||||
#if defined(ARDUINO_ARCH_ESP8266)
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
@@ -155,8 +155,8 @@
|
|||||||
#include "drivers/SPIFlash/SPIFlash.cpp"
|
#include "drivers/SPIFlash/SPIFlash.cpp"
|
||||||
#endif
|
#endif
|
||||||
#include "core/MyTransport.cpp"
|
#include "core/MyTransport.cpp"
|
||||||
#if defined(MY_RADIO_NRF24) && defined(MY_RADIO_RFM69)
|
#if (defined(MY_RADIO_NRF24) && defined(MY_RADIO_RFM69)) || (defined(MY_RADIO_NRF24) && defined(MY_RS485)) || (defined(MY_RADIO_RFM69) && defined(MY_RS485))
|
||||||
#error Only one radio driver can be activated
|
#error Only one forward link driver can be activated
|
||||||
#endif
|
#endif
|
||||||
#if defined(MY_RADIO_NRF24)
|
#if defined(MY_RADIO_NRF24)
|
||||||
#if defined(MY_RF24_ENABLE_ENCRYPTION)
|
#if defined(MY_RF24_ENABLE_ENCRYPTION)
|
||||||
@@ -164,6 +164,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "drivers/RF24/RF24.cpp"
|
#include "drivers/RF24/RF24.cpp"
|
||||||
#include "core/MyTransportNRF24.cpp"
|
#include "core/MyTransportNRF24.cpp"
|
||||||
|
#elif defined(MY_RS485)
|
||||||
|
#include "drivers/AltSoftSerial/AltSoftSerial.cpp"
|
||||||
|
#include "core/MyTransportRS485.cpp"
|
||||||
#elif defined(MY_RADIO_RFM69)
|
#elif defined(MY_RADIO_RFM69)
|
||||||
#include "drivers/RFM69/RFM69.cpp"
|
#include "drivers/RFM69/RFM69.cpp"
|
||||||
#include "core/MyTransportRFM69.cpp"
|
#include "core/MyTransportRFM69.cpp"
|
||||||
@@ -184,7 +187,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MY_GATEWAY_FEATURE) && !defined(MY_RADIO_FEATURE)
|
#if !defined(MY_GATEWAY_FEATURE) && !defined(MY_RADIO_FEATURE)
|
||||||
#error No radio or gateway feature activated. This means nowhere to send messages! Pretty pointless.
|
#error No forward link or gateway feature activated. This means nowhere to send messages! Pretty pointless.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,320 @@
|
|||||||
|
/**
|
||||||
|
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||||
|
* between your home built sensors/actuators and HA controller of choice.
|
||||||
|
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||||
|
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||||
|
* network topology allowing messages to be routed to nodes.
|
||||||
|
*
|
||||||
|
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||||
|
* Copyright (C) 2013-2015 Sensnology AB
|
||||||
|
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||||
|
*
|
||||||
|
* Documentation: http://www.mysensors.org
|
||||||
|
* Support Forum: http://forum.mysensors.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Majenko Technologies and S.J.Hoeksma
|
||||||
|
* Copyright (c) 2015, LeoDesigner
|
||||||
|
* https://github.com/leodesigner/mysensors-serial-transport
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those
|
||||||
|
* of the authors and should not be interpreted as representing official policies,
|
||||||
|
* either expressed or implied, of Majenko Technologies.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
// transport(Serial,0,-1); // serial port, node, dePin (-1 disabled)
|
||||||
|
|
||||||
|
// Serial Transport
|
||||||
|
|
||||||
|
|
||||||
|
#include "MyConfig.h"
|
||||||
|
#include "MyTransport.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
|
#include <Arduino.h>
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "MyTransport.h"
|
||||||
|
|
||||||
|
// We only use SYS_PACK in this application
|
||||||
|
#define ICSC_SYS_PACK 0x58
|
||||||
|
|
||||||
|
// Receiving header information
|
||||||
|
char _header[6];
|
||||||
|
|
||||||
|
// Reception state machine control and storage variables
|
||||||
|
unsigned char _recPhase;
|
||||||
|
unsigned char _recPos;
|
||||||
|
unsigned char _recCommand;
|
||||||
|
unsigned char _recLen;
|
||||||
|
unsigned char _recStation;
|
||||||
|
unsigned char _recSender;
|
||||||
|
unsigned char _recCS;
|
||||||
|
unsigned char _recCalcCS;
|
||||||
|
|
||||||
|
AltSoftSerial _dev;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char _nodeId;
|
||||||
|
char _data[MY_RS485_MAX_MESSAGE_LENGTH];
|
||||||
|
uint8_t _packet_len;
|
||||||
|
unsigned char _packet_from;
|
||||||
|
bool _packet_received;
|
||||||
|
|
||||||
|
// Packet wrapping characters, defined in standard ASCII table
|
||||||
|
#define SOH 1
|
||||||
|
#define STX 2
|
||||||
|
#define ETX 3
|
||||||
|
#define EOT 4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Reset the state machine and release the data pointer
|
||||||
|
void _serialReset(){
|
||||||
|
_recPhase = 0;
|
||||||
|
_recPos = 0;
|
||||||
|
_recLen = 0;
|
||||||
|
_recCommand = 0;
|
||||||
|
_recCS = 0;
|
||||||
|
_recCalcCS = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the main reception state machine. Progress through the states
|
||||||
|
// is keyed on either special control characters, or counted number of bytes
|
||||||
|
// received. If all the data is in the right format, and the calculated
|
||||||
|
// checksum matches the received checksum, AND the destination station is
|
||||||
|
// our station ID, then look for a registered command that matches the
|
||||||
|
// command code. If all the above is true, execute the command's
|
||||||
|
// function.
|
||||||
|
boolean _serialProcess()
|
||||||
|
{
|
||||||
|
char inch;
|
||||||
|
unsigned char i;
|
||||||
|
if (!_dev.available()) return false;
|
||||||
|
|
||||||
|
while(_dev.available()) {
|
||||||
|
inch = _dev.read();
|
||||||
|
|
||||||
|
switch(_recPhase) {
|
||||||
|
|
||||||
|
// Case 0 looks for the header. Bytes arrive in the serial interface and get
|
||||||
|
// shifted through a header buffer. When the start and end characters in
|
||||||
|
// the buffer match the SOH/STX pair, and the destination station ID matches
|
||||||
|
// our ID, save the header information and progress to the next state.
|
||||||
|
case 0:
|
||||||
|
memcpy(&_header[0],&_header[1],5);
|
||||||
|
_header[5] = inch;
|
||||||
|
if ((_header[0] == SOH) && (_header[5] == STX) && (_header[1] != _header[2])) {
|
||||||
|
_recCalcCS = 0;
|
||||||
|
_recStation = _header[1];
|
||||||
|
_recSender = _header[2];
|
||||||
|
_recCommand = _header[3];
|
||||||
|
_recLen = _header[4];
|
||||||
|
|
||||||
|
for (i=1; i<=4; i++) {
|
||||||
|
_recCalcCS += _header[i];
|
||||||
|
}
|
||||||
|
_recPhase = 1;
|
||||||
|
_recPos = 0;
|
||||||
|
|
||||||
|
//Check if we should process this message
|
||||||
|
//We reject the message if we are the sender
|
||||||
|
//We reject if we are not the receiver and message is not a broadcast
|
||||||
|
if ((_recSender == _nodeId) ||
|
||||||
|
(_recStation != _nodeId &&
|
||||||
|
_recStation != BROADCAST_ADDRESS)) {
|
||||||
|
_dev.print(" wrongid: ");
|
||||||
|
_dev.print(_recStation);
|
||||||
|
_dev.print(" - ");
|
||||||
|
_dev.println(_nodeId);
|
||||||
|
_serialReset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_recLen == 0) {
|
||||||
|
_recPhase = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Case 1 receives the data portion of the packet. Read in "_recLen" number
|
||||||
|
// of bytes and store them in the _data array.
|
||||||
|
case 1:
|
||||||
|
_data[_recPos++] = inch;
|
||||||
|
_recCalcCS += inch;
|
||||||
|
if (_recPos == _recLen) {
|
||||||
|
_recPhase = 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// After the data comes a single ETX character. Do we have it? If not,
|
||||||
|
// reset the state machine to default and start looking for a new header.
|
||||||
|
case 2:
|
||||||
|
// Packet properly terminated?
|
||||||
|
if (inch == ETX) {
|
||||||
|
_recPhase = 3;
|
||||||
|
} else {
|
||||||
|
_serialReset();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Next comes the checksum. We have already calculated it from the incoming
|
||||||
|
// data, so just store the incoming checksum byte for later.
|
||||||
|
case 3:
|
||||||
|
_recCS = inch;
|
||||||
|
_recPhase = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// The final state - check the last character is EOT and that the checksum matches.
|
||||||
|
// If that test passes, then look for a valid command callback to execute.
|
||||||
|
// Execute it if found.
|
||||||
|
case 4:
|
||||||
|
if (inch == EOT) {
|
||||||
|
if (_recCS == _recCalcCS) {
|
||||||
|
// First, check for system level commands. It is possible
|
||||||
|
// to register your own callback as well for system level
|
||||||
|
// commands which will be called after the system default
|
||||||
|
// hook.
|
||||||
|
|
||||||
|
switch (_recCommand) {
|
||||||
|
case ICSC_SYS_PACK:
|
||||||
|
_packet_from = _recSender;
|
||||||
|
_packet_len = _recLen;
|
||||||
|
_packet_received = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Clear the data
|
||||||
|
_serialReset();
|
||||||
|
//Return true, we have processed one command
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool transportSend(uint8_t to, const void* data, uint8_t len)
|
||||||
|
{
|
||||||
|
const char *datap = static_cast<char const *>(data);
|
||||||
|
unsigned char i;
|
||||||
|
unsigned char cs = 0;
|
||||||
|
unsigned char del;
|
||||||
|
|
||||||
|
// This is how many times to try and transmit before failing.
|
||||||
|
unsigned char timeout = 10;
|
||||||
|
|
||||||
|
// Let's start out by looking for a collision. If there has been anything seen in
|
||||||
|
// the last millisecond, then wait for a random time and check again.
|
||||||
|
|
||||||
|
while (_serialProcess()) {
|
||||||
|
del = rand() % 20;
|
||||||
|
for (i = 0; i < del; i++) {
|
||||||
|
delay(1);
|
||||||
|
_serialProcess();
|
||||||
|
}
|
||||||
|
timeout--;
|
||||||
|
if (timeout == 0) {
|
||||||
|
// Failed to transmit!!!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start of header by writing multiple SOH
|
||||||
|
for(byte w=0;w<1;w++) _dev.write(SOH);
|
||||||
|
_dev.write(to); // Destination address
|
||||||
|
cs += to;
|
||||||
|
_dev.write(_nodeId); // Source address
|
||||||
|
cs += _nodeId;
|
||||||
|
_dev.write(ICSC_SYS_PACK); // Command code
|
||||||
|
cs += ICSC_SYS_PACK;
|
||||||
|
_dev.write(len); // Length of text
|
||||||
|
cs += len;
|
||||||
|
_dev.write(STX); // Start of text
|
||||||
|
for(i=0; i<len; i++) {
|
||||||
|
_dev.write(datap[i]); // Text bytes
|
||||||
|
cs += datap[i];
|
||||||
|
}
|
||||||
|
_dev.write(ETX); // End of text
|
||||||
|
_dev.write(cs);
|
||||||
|
_dev.write(EOT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool transportInit() {
|
||||||
|
// Reset the state machine
|
||||||
|
_dev.begin(MY_RS485_BAUD_RATE);
|
||||||
|
_serialReset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void transportSetAddress(uint8_t address) {
|
||||||
|
_nodeId = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t transportGetAddress() {
|
||||||
|
return _nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool transportAvailable(uint8_t *to) {
|
||||||
|
_serialProcess();
|
||||||
|
if (_packet_received == true) {
|
||||||
|
if (_recStation==BROADCAST_ADDRESS) {
|
||||||
|
*to = BROADCAST_ADDRESS;
|
||||||
|
}
|
||||||
|
else { *to = _nodeId; }
|
||||||
|
}
|
||||||
|
return _packet_received;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t transportReceive(void* data) {
|
||||||
|
if (_packet_received) {
|
||||||
|
memcpy(data,_data,_packet_len);
|
||||||
|
_packet_received = false;
|
||||||
|
return _packet_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transportPowerDown() {
|
||||||
|
// Nothing to shut down here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,317 @@
|
|||||||
|
/* An Alternative Software Serial Library
|
||||||
|
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
|
||||||
|
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Version 1.2: Support Teensy 3.x
|
||||||
|
//
|
||||||
|
// Version 1.1: Improve performance in receiver code
|
||||||
|
//
|
||||||
|
// Version 1.0: Initial Release
|
||||||
|
|
||||||
|
|
||||||
|
#include "AltSoftSerial.h"
|
||||||
|
#include "config/AltSoftSerial_Boards.h"
|
||||||
|
#include "config/AltSoftSerial_Timers.h"
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/** Initialization **/
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
static uint16_t ticks_per_bit=0;
|
||||||
|
bool AltSoftSerial::timing_error=false;
|
||||||
|
|
||||||
|
static uint8_t rx_state;
|
||||||
|
static uint8_t rx_byte;
|
||||||
|
static uint8_t rx_bit = 0;
|
||||||
|
static uint16_t rx_target;
|
||||||
|
static uint16_t rx_stop_ticks=0;
|
||||||
|
static volatile uint8_t rx_buffer_head;
|
||||||
|
static volatile uint8_t rx_buffer_tail;
|
||||||
|
#define RX_BUFFER_SIZE 80
|
||||||
|
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
|
||||||
|
|
||||||
|
static volatile uint8_t tx_state=0;
|
||||||
|
static uint8_t tx_byte;
|
||||||
|
static uint8_t tx_bit;
|
||||||
|
static volatile uint8_t tx_buffer_head;
|
||||||
|
static volatile uint8_t tx_buffer_tail;
|
||||||
|
#define TX_BUFFER_SIZE 68
|
||||||
|
static volatile uint8_t tx_buffer[RX_BUFFER_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INPUT_PULLUP
|
||||||
|
#define INPUT_PULLUP INPUT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void AltSoftSerial::init(uint32_t cycles_per_bit)
|
||||||
|
{
|
||||||
|
if (cycles_per_bit < 7085) {
|
||||||
|
CONFIG_TIMER_NOPRESCALE();
|
||||||
|
} else {
|
||||||
|
cycles_per_bit /= 8;
|
||||||
|
if (cycles_per_bit < 7085) {
|
||||||
|
CONFIG_TIMER_PRESCALE_8();
|
||||||
|
} else {
|
||||||
|
return; // minimum 283 baud at 16 MHz clock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ticks_per_bit = cycles_per_bit;
|
||||||
|
rx_stop_ticks = cycles_per_bit * 37 / 4;
|
||||||
|
pinMode(INPUT_CAPTURE_PIN, INPUT_PULLUP);
|
||||||
|
digitalWrite(OUTPUT_COMPARE_A_PIN, HIGH);
|
||||||
|
pinMode(OUTPUT_COMPARE_A_PIN, OUTPUT);
|
||||||
|
rx_state = 0;
|
||||||
|
rx_buffer_head = 0;
|
||||||
|
rx_buffer_tail = 0;
|
||||||
|
tx_state = 0;
|
||||||
|
tx_buffer_head = 0;
|
||||||
|
tx_buffer_tail = 0;
|
||||||
|
ENABLE_INT_INPUT_CAPTURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AltSoftSerial::end(void)
|
||||||
|
{
|
||||||
|
DISABLE_INT_COMPARE_B();
|
||||||
|
DISABLE_INT_INPUT_CAPTURE();
|
||||||
|
flushInput();
|
||||||
|
flushOutput();
|
||||||
|
DISABLE_INT_COMPARE_A();
|
||||||
|
// TODO: restore timer to original settings?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/** Transmission **/
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
void AltSoftSerial::writeByte(uint8_t b)
|
||||||
|
{
|
||||||
|
uint8_t intr_state, head;
|
||||||
|
|
||||||
|
head = tx_buffer_head + 1;
|
||||||
|
if (head >= TX_BUFFER_SIZE) head = 0;
|
||||||
|
while (tx_buffer_tail == head) ; // wait until space in buffer
|
||||||
|
intr_state = SREG;
|
||||||
|
cli();
|
||||||
|
if (tx_state) {
|
||||||
|
tx_buffer[head] = b;
|
||||||
|
tx_buffer_head = head;
|
||||||
|
} else {
|
||||||
|
tx_state = 1;
|
||||||
|
tx_byte = b;
|
||||||
|
tx_bit = 0;
|
||||||
|
ENABLE_INT_COMPARE_A();
|
||||||
|
CONFIG_MATCH_CLEAR();
|
||||||
|
SET_COMPARE_A(GET_TIMER_COUNT() + 16);
|
||||||
|
}
|
||||||
|
SREG = intr_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISR(COMPARE_A_INTERRUPT)
|
||||||
|
{
|
||||||
|
uint8_t state, byte, bit, head, tail;
|
||||||
|
uint16_t target;
|
||||||
|
|
||||||
|
state = tx_state;
|
||||||
|
byte = tx_byte;
|
||||||
|
target = GET_COMPARE_A();
|
||||||
|
while (state < 9) {
|
||||||
|
target += ticks_per_bit;
|
||||||
|
bit = byte & 1;
|
||||||
|
byte >>= 1;
|
||||||
|
state++;
|
||||||
|
if (bit != tx_bit) {
|
||||||
|
if (bit) {
|
||||||
|
CONFIG_MATCH_SET();
|
||||||
|
} else {
|
||||||
|
CONFIG_MATCH_CLEAR();
|
||||||
|
}
|
||||||
|
SET_COMPARE_A(target);
|
||||||
|
tx_bit = bit;
|
||||||
|
tx_byte = byte;
|
||||||
|
tx_state = state;
|
||||||
|
// TODO: how to detect timing_error?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state == 9) {
|
||||||
|
tx_state = 10;
|
||||||
|
CONFIG_MATCH_SET();
|
||||||
|
SET_COMPARE_A(target + ticks_per_bit);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
head = tx_buffer_head;
|
||||||
|
tail = tx_buffer_tail;
|
||||||
|
if (head == tail) {
|
||||||
|
tx_state = 0;
|
||||||
|
CONFIG_MATCH_NORMAL();
|
||||||
|
DISABLE_INT_COMPARE_A();
|
||||||
|
} else {
|
||||||
|
tx_state = 1;
|
||||||
|
if (++tail >= TX_BUFFER_SIZE) tail = 0;
|
||||||
|
tx_buffer_tail = tail;
|
||||||
|
tx_byte = tx_buffer[tail];
|
||||||
|
tx_bit = 0;
|
||||||
|
CONFIG_MATCH_CLEAR();
|
||||||
|
SET_COMPARE_A(target + ticks_per_bit);
|
||||||
|
// TODO: how to detect timing_error?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AltSoftSerial::flushOutput(void)
|
||||||
|
{
|
||||||
|
while (tx_state) /* wait */ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/** Reception **/
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
|
||||||
|
ISR(CAPTURE_INTERRUPT)
|
||||||
|
{
|
||||||
|
uint8_t state, bit, head;
|
||||||
|
uint16_t capture, target;
|
||||||
|
int16_t offset;
|
||||||
|
|
||||||
|
capture = GET_INPUT_CAPTURE();
|
||||||
|
bit = rx_bit;
|
||||||
|
if (bit) {
|
||||||
|
CONFIG_CAPTURE_FALLING_EDGE();
|
||||||
|
rx_bit = 0;
|
||||||
|
} else {
|
||||||
|
CONFIG_CAPTURE_RISING_EDGE();
|
||||||
|
rx_bit = 0x80;
|
||||||
|
}
|
||||||
|
state = rx_state;
|
||||||
|
if (state == 0) {
|
||||||
|
if (!bit) {
|
||||||
|
SET_COMPARE_B(capture + rx_stop_ticks);
|
||||||
|
ENABLE_INT_COMPARE_B();
|
||||||
|
rx_target = capture + ticks_per_bit + ticks_per_bit/2;
|
||||||
|
rx_state = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
target = rx_target;
|
||||||
|
while (1) {
|
||||||
|
offset = capture - target;
|
||||||
|
if (offset < 0) break;
|
||||||
|
rx_byte = (rx_byte >> 1) | rx_bit;
|
||||||
|
target += ticks_per_bit;
|
||||||
|
state++;
|
||||||
|
if (state >= 9) {
|
||||||
|
DISABLE_INT_COMPARE_B();
|
||||||
|
head = rx_buffer_head + 1;
|
||||||
|
if (head >= RX_BUFFER_SIZE) head = 0;
|
||||||
|
if (head != rx_buffer_tail) {
|
||||||
|
rx_buffer[head] = rx_byte;
|
||||||
|
rx_buffer_head = head;
|
||||||
|
}
|
||||||
|
CONFIG_CAPTURE_FALLING_EDGE();
|
||||||
|
rx_bit = 0;
|
||||||
|
rx_state = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rx_target = target;
|
||||||
|
rx_state = state;
|
||||||
|
}
|
||||||
|
//if (GET_TIMER_COUNT() - capture > ticks_per_bit) AltSoftSerial::timing_error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(COMPARE_B_INTERRUPT)
|
||||||
|
{
|
||||||
|
uint8_t head, state, bit;
|
||||||
|
|
||||||
|
DISABLE_INT_COMPARE_B();
|
||||||
|
CONFIG_CAPTURE_FALLING_EDGE();
|
||||||
|
state = rx_state;
|
||||||
|
bit = rx_bit ^ 0x80;
|
||||||
|
while (state < 9) {
|
||||||
|
rx_byte = (rx_byte >> 1) | bit;
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
head = rx_buffer_head + 1;
|
||||||
|
if (head >= RX_BUFFER_SIZE) head = 0;
|
||||||
|
if (head != rx_buffer_tail) {
|
||||||
|
rx_buffer[head] = rx_byte;
|
||||||
|
rx_buffer_head = head;
|
||||||
|
}
|
||||||
|
rx_state = 0;
|
||||||
|
CONFIG_CAPTURE_FALLING_EDGE();
|
||||||
|
rx_bit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AltSoftSerial::read(void)
|
||||||
|
{
|
||||||
|
uint8_t head, tail, out;
|
||||||
|
|
||||||
|
head = rx_buffer_head;
|
||||||
|
tail = rx_buffer_tail;
|
||||||
|
if (head == tail) return -1;
|
||||||
|
if (++tail >= RX_BUFFER_SIZE) tail = 0;
|
||||||
|
out = rx_buffer[tail];
|
||||||
|
rx_buffer_tail = tail;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AltSoftSerial::peek(void)
|
||||||
|
{
|
||||||
|
uint8_t head, tail;
|
||||||
|
|
||||||
|
head = rx_buffer_head;
|
||||||
|
tail = rx_buffer_tail;
|
||||||
|
if (head == tail) return -1;
|
||||||
|
return rx_buffer[tail];
|
||||||
|
}
|
||||||
|
|
||||||
|
int AltSoftSerial::available(void)
|
||||||
|
{
|
||||||
|
uint8_t head, tail;
|
||||||
|
|
||||||
|
head = rx_buffer_head;
|
||||||
|
tail = rx_buffer_tail;
|
||||||
|
if (head >= tail) return head - tail;
|
||||||
|
return RX_BUFFER_SIZE + head - tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AltSoftSerial::flushInput(void)
|
||||||
|
{
|
||||||
|
rx_buffer_head = rx_buffer_tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ALTSS_USE_FTM0
|
||||||
|
void ftm0_isr(void)
|
||||||
|
{
|
||||||
|
uint32_t flags = FTM0_STATUS;
|
||||||
|
FTM0_STATUS = 0;
|
||||||
|
if (flags & (1<<5)) altss_capture_interrupt();
|
||||||
|
if (flags & (1<<6)) altss_compare_a_interrupt();
|
||||||
|
if (flags & (1<<0)) altss_compare_b_interrupt();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/* An Alternative Software Serial Library
|
||||||
|
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
|
||||||
|
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AltSoftSerial_h
|
||||||
|
#define AltSoftSerial_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#include "pins_arduino.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__arm__) && defined(CORE_TEENSY)
|
||||||
|
#define ALTSS_BASE_FREQ F_BUS
|
||||||
|
#else
|
||||||
|
#define ALTSS_BASE_FREQ F_CPU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class AltSoftSerial : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AltSoftSerial() { }
|
||||||
|
~AltSoftSerial() { end(); }
|
||||||
|
static void begin(uint32_t baud) { init((ALTSS_BASE_FREQ + baud / 2) / baud); }
|
||||||
|
static void end();
|
||||||
|
int peek();
|
||||||
|
int read();
|
||||||
|
int available();
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
size_t write(uint8_t byte) { writeByte(byte); return 1; }
|
||||||
|
void flush() { flushOutput(); }
|
||||||
|
#else
|
||||||
|
void write(uint8_t byte) { writeByte(byte); }
|
||||||
|
void flush() { flushInput(); }
|
||||||
|
#endif
|
||||||
|
using Print::write;
|
||||||
|
static void flushInput();
|
||||||
|
static void flushOutput();
|
||||||
|
// for drop-in compatibility with NewSoftSerial, rxPin & txPin ignored
|
||||||
|
//AltSoftSerial(uint8_t rxPin, uint8_t txPin, bool inverse = false) { }
|
||||||
|
bool listen() { return false; }
|
||||||
|
bool isListening() { return true; }
|
||||||
|
bool overflow() { bool r = timing_error; timing_error = false; return r; }
|
||||||
|
static int library_version() { return 1; }
|
||||||
|
static void enable_timer0(bool) { }
|
||||||
|
static bool timing_error;
|
||||||
|
private:
|
||||||
|
static void init(uint32_t cycles_per_bit);
|
||||||
|
static void writeByte(uint8_t byte);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#AltSoftSerial Library#
|
||||||
|
|
||||||
|
Improved software emulated serial, using hardware timers for precise signal
|
||||||
|
timing and availability of CPU time for other libraries to respond to interrupts
|
||||||
|
during data AltSoftSerial data transmission and reception.
|
||||||
|
|
||||||
|
http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
|
||||||
|
|
||||||
|

|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/* An Alternative Software Serial Library
|
||||||
|
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
|
||||||
|
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Teensy 2.0
|
||||||
|
//
|
||||||
|
#if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER1
|
||||||
|
//#define INPUT_CAPTURE_PIN 22 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 14 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 15 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 4 // unusable PWM
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER3
|
||||||
|
#define INPUT_CAPTURE_PIN 10 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 9 // transmit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Teensy++ 2.0
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 4 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 25 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 26 // unusable PWM
|
||||||
|
#define OUTPUT_COMPARE_C_PIN 27 // unusable PWM
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER3
|
||||||
|
//#define INPUT_CAPTURE_PIN 17 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 16 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 15 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 14 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
// Teensy 3.0 & 3.1
|
||||||
|
//
|
||||||
|
#elif defined(__MK20DX128__) || defined(__MK20DX256__)
|
||||||
|
#define ALTSS_USE_FTM0
|
||||||
|
#define INPUT_CAPTURE_PIN 20 // receive (FTM0_CH5)
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 21 // transmit (FTM0_CH6)
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 22 // unusable PWM (FTM0_CH0)
|
||||||
|
#define OUTPUT_COMPARE_C_PIN 23 // PWM usable fixed freq
|
||||||
|
#define OUTPUT_COMPARE_D_PIN 5 // PWM usable fixed freq
|
||||||
|
#define OUTPUT_COMPARE_E_PIN 6 // PWM usable fixed freq
|
||||||
|
#define OUTPUT_COMPARE_F_PIN 9 // PWM usable fixed freq
|
||||||
|
#define OUTPUT_COMPARE_G_PIN 10 // PWM usable fixed freq
|
||||||
|
|
||||||
|
|
||||||
|
// Wiring-S
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_ATmega644P__) && defined(WIRING)
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 6 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 5 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 4 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Arduino Uno, Duemilanove, LilyPad, etc
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 8 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 9 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
// Arduino Leonardo & Yun (from Cristian Maglie)
|
||||||
|
//
|
||||||
|
#elif defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_LEONARDO) || defined(__AVR_ATmega32U4__)
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER1
|
||||||
|
//#define INPUT_CAPTURE_PIN 4 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 9 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 11 // unusable PWM
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER3
|
||||||
|
#define INPUT_CAPTURE_PIN 13 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 5 // transmit
|
||||||
|
|
||||||
|
|
||||||
|
// Arduino Mega
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER4
|
||||||
|
//#define INPUT_CAPTURE_PIN 49 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 6 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 7 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 8 // unusable PWM
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER5
|
||||||
|
#define INPUT_CAPTURE_PIN 48 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 46 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 45 // unusable PWM
|
||||||
|
#define OUTPUT_COMPARE_C_PIN 44 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Sanguino
|
||||||
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 14 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 13 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 12 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
// Unknown board
|
||||||
|
#else
|
||||||
|
#error "Please define your board timer and pins"
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
/* An Alternative Software Serial Library
|
||||||
|
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
|
||||||
|
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(ALTSS_USE_TIMER1)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS10))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS11))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR1A = TCCR1A & ~((1<<COM1A1) | (1<<COM1A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR1A = (TCCR1A | (1<<COM1A1)) & ~(1<<COM1A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR1A = TCCR1A | ((1<<COM1A1) | (1<<COM1A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR1B &= ~(1<<ICES1))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR1B |= (1<<ICES1))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR1 = (1<<ICF1), TIMSK1 = (1<<ICIE1))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR1 = (1<<OCF1A), TIMSK1 |= (1<<OCIE1A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR1 = (1<<OCF1B), TIMSK1 |= (1<<OCIE1B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK1 &= ~(1<<ICIE1))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK1 &= ~(1<<OCIE1A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK1 &= ~(1<<OCIE1B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT1)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR1)
|
||||||
|
#define GET_COMPARE_A() (OCR1A)
|
||||||
|
#define GET_COMPARE_B() (OCR1B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR1A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR1B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER1_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER1_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER1_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_TIMER3)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS30))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS31))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR3A = TCCR3A & ~((1<<COM3A1) | (1<<COM3A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR3A = (TCCR3A & ~(1<<COM3A1)) | (1<<COM3A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR3A = (TCCR3A | (1<<COM3A1)) & ~(1<<COM3A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR3A = TCCR3A | ((1<<COM3A1) | (1<<COM3A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR3B &= ~(1<<ICES3))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR3B |= (1<<ICES3))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR3 = (1<<ICF3), TIMSK3 = (1<<ICIE3))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR3 = (1<<OCF3A), TIMSK3 |= (1<<OCIE3A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR3 = (1<<OCF3B), TIMSK3 |= (1<<OCIE3B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK3 &= ~(1<<ICIE3))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK3 &= ~(1<<OCIE3A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK3 &= ~(1<<OCIE3B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT3)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR3)
|
||||||
|
#define GET_COMPARE_A() (OCR3A)
|
||||||
|
#define GET_COMPARE_B() (OCR3B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR3A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR3B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER3_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER3_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER3_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_TIMER4)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS40))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS41))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR4A = TCCR4A & ~((1<<COM4A1) | (1<<COM4A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR4A = (TCCR4A & ~(1<<COM4A1)) | (1<<COM4A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR4A = (TCCR4A | (1<<COM4A1)) & ~(1<<COM4A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR4A = TCCR4A | ((1<<COM4A1) | (1<<COM4A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR4B &= ~(1<<ICES4))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR4B |= (1<<ICES4))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR4 = (1<<ICF4), TIMSK4 = (1<<ICIE4))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR4 = (1<<OCF4A), TIMSK4 |= (1<<OCIE4A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR4 = (1<<OCF4B), TIMSK4 |= (1<<OCIE4B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK4 &= ~(1<<ICIE4))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK4 &= ~(1<<OCIE4A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK4 &= ~(1<<OCIE4B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT4)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR4)
|
||||||
|
#define GET_COMPARE_A() (OCR4A)
|
||||||
|
#define GET_COMPARE_B() (OCR4B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR4A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR4B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER4_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER4_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER4_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_TIMER5)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS50))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS51))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR5A = TCCR5A & ~((1<<COM5A1) | (1<<COM5A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR5A = (TCCR5A & ~(1<<COM5A1)) | (1<<COM5A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR5A = (TCCR5A | (1<<COM5A1)) & ~(1<<COM5A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR5A = TCCR5A | ((1<<COM5A1) | (1<<COM5A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR5B &= ~(1<<ICES5))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR5B |= (1<<ICES5))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR5 = (1<<ICF5), TIMSK5 = (1<<ICIE5))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR5 = (1<<OCF5A), TIMSK5 |= (1<<OCIE5A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR5 = (1<<OCF5B), TIMSK5 |= (1<<OCIE5B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK5 &= ~(1<<ICIE5))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK5 &= ~(1<<OCIE5A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK5 &= ~(1<<OCIE5B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT5)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR5)
|
||||||
|
#define GET_COMPARE_A() (OCR5A)
|
||||||
|
#define GET_COMPARE_B() (OCR5B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR5A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR5B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER5_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER5_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER5_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_FTM0)
|
||||||
|
// CH5 = input capture (input, pin 20)
|
||||||
|
// CH6 = compare a (output, pin 21)
|
||||||
|
// CH0 = compare b (input timeout)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
|
||||||
|
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \
|
||||||
|
digitalWriteFast(21, HIGH); \
|
||||||
|
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
|
||||||
|
NVIC_ENABLE_IRQ(IRQ_FTM0);
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
|
||||||
|
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(3); \
|
||||||
|
digitalWriteFast(21, HIGH); \
|
||||||
|
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
|
||||||
|
NVIC_ENABLE_IRQ(IRQ_FTM0);
|
||||||
|
#define CONFIG_MATCH_NORMAL() (FTM0_C6SC = 0)
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x14)
|
||||||
|
#define CONFIG_MATCH_CLEAR() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x18)
|
||||||
|
#define CONFIG_MATCH_SET() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x1C)
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (FTM0_C5SC = (FTM0_C5SC & 0xC3) | 0x08)
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (FTM0_C5SC = (FTM0_C5SC & 0xC3) | 0x04)
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() FTM0_C5SC = 0x48; \
|
||||||
|
CORE_PIN20_CONFIG = PORT_PCR_MUX(4)|PORT_PCR_PE|PORT_PCR_PS
|
||||||
|
#define ENABLE_INT_COMPARE_A() FTM0_C6SC |= 0x40; \
|
||||||
|
CORE_PIN21_CONFIG = PORT_PCR_MUX(4)|PORT_PCR_DSE|PORT_PCR_SRE
|
||||||
|
#define ENABLE_INT_COMPARE_B() (FTM0_C0SC |= 0x40)
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() FTM0_C5SC &= ~0x40; \
|
||||||
|
CORE_PIN20_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_PE|PORT_PCR_PS
|
||||||
|
#define DISABLE_INT_COMPARE_A() FTM0_C6SC &= ~0x40; \
|
||||||
|
CORE_PIN21_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE; \
|
||||||
|
digitalWriteFast(21, HIGH)
|
||||||
|
#define DISABLE_INT_COMPARE_B() (FTM0_C0SC &= ~0x40)
|
||||||
|
#define GET_TIMER_COUNT() (FTM0_CNT)
|
||||||
|
#define GET_INPUT_CAPTURE() (FTM0_C5V)
|
||||||
|
#define GET_COMPARE_A() (FTM0_C6V)
|
||||||
|
#define GET_COMPARE_B() (FTM0_C0V)
|
||||||
|
#define SET_COMPARE_A(val) (FTM0_C6V = val)
|
||||||
|
#define SET_COMPARE_B(val) (FTM0_C0V = val)
|
||||||
|
#define CAPTURE_INTERRUPT altss_capture_interrupt
|
||||||
|
#define COMPARE_A_INTERRUPT altss_compare_a_interrupt
|
||||||
|
#define COMPARE_B_INTERRUPT altss_compare_b_interrupt
|
||||||
|
#ifdef ISR
|
||||||
|
#undef ISR
|
||||||
|
#endif
|
||||||
|
#define ISR(f) static void f (void)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
|
||||||
|
// Teensy 2.0
|
||||||
|
//
|
||||||
|
#if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER1
|
||||||
|
//#define INPUT_CAPTURE_PIN 22 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 14 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 15 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 4 // unusable PWM
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER3
|
||||||
|
#define INPUT_CAPTURE_PIN 10 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 9 // transmit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Teensy++ 2.0
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 4 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 25 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 26 // unusable PWM
|
||||||
|
#define OUTPUT_COMPARE_C_PIN 27 // unusable PWM
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER3
|
||||||
|
//#define INPUT_CAPTURE_PIN 17 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 16 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 15 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 14 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Wiring-S
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_ATmega644P__) && defined(WIRING)
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 6 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 5 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 4 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Arduino Uno, Duemilanove, LilyPad, etc
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 8 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 9 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
// Arduino Leonardo & Yun (from Cristian Maglie)
|
||||||
|
//
|
||||||
|
#elif defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_LEONARDO)
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER1
|
||||||
|
//#define INPUT_CAPTURE_PIN 4 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 9 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 11 // unusable PWM
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER3
|
||||||
|
#define INPUT_CAPTURE_PIN 13 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 5 // transmit
|
||||||
|
|
||||||
|
|
||||||
|
// Arduino Mega
|
||||||
|
//
|
||||||
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
|
||||||
|
//#define ALTSS_USE_TIMER4
|
||||||
|
//#define INPUT_CAPTURE_PIN 49 // receive
|
||||||
|
//#define OUTPUT_COMPARE_A_PIN 6 // transmit
|
||||||
|
//#define OUTPUT_COMPARE_B_PIN 7 // unusable PWM
|
||||||
|
//#define OUTPUT_COMPARE_C_PIN 8 // unusable PWM
|
||||||
|
|
||||||
|
#define ALTSS_USE_TIMER5
|
||||||
|
#define INPUT_CAPTURE_PIN 48 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 46 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 45 // unusable PWM
|
||||||
|
#define OUTPUT_COMPARE_C_PIN 44 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Sanguino
|
||||||
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
|
#define ALTSS_USE_TIMER1
|
||||||
|
#define INPUT_CAPTURE_PIN 14 // receive
|
||||||
|
#define OUTPUT_COMPARE_A_PIN 13 // transmit
|
||||||
|
#define OUTPUT_COMPARE_B_PIN 12 // unusable PWM
|
||||||
|
|
||||||
|
|
||||||
|
// Unknown board
|
||||||
|
#else
|
||||||
|
#error "Please define your board timer and pins"
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
#if defined(ALTSS_USE_TIMER1)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS10))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS11))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR1A = TCCR1A & ~((1<<COM1A1) | (1<<COM1A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR1A = (TCCR1A | (1<<COM1A1)) & ~(1<<COM1A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR1A = TCCR1A | ((1<<COM1A1) | (1<<COM1A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR1B &= ~(1<<ICES1))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR1B |= (1<<ICES1))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR1 = (1<<ICF1), TIMSK1 = (1<<ICIE1))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR1 = (1<<OCF1A), TIMSK1 |= (1<<OCIE1A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR1 = (1<<OCF1B), TIMSK1 |= (1<<OCIE1B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK1 &= ~(1<<ICIE1))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK1 &= ~(1<<OCIE1A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK1 &= ~(1<<OCIE1B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT1)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR1)
|
||||||
|
#define GET_COMPARE_A() (OCR1A)
|
||||||
|
#define GET_COMPARE_B() (OCR1B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR1A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR1B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER1_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER1_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER1_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_TIMER3)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS30))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS31))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR3A = TCCR3A & ~((1<<COM3A1) | (1<<COM3A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR3A = (TCCR3A & ~(1<<COM3A1)) | (1<<COM3A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR3A = (TCCR3A | (1<<COM3A1)) & ~(1<<COM3A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR3A = TCCR3A | ((1<<COM3A1) | (1<<COM3A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR3B &= ~(1<<ICES3))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR3B |= (1<<ICES3))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR3 = (1<<ICF3), TIMSK3 = (1<<ICIE3))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR3 = (1<<OCF3A), TIMSK3 |= (1<<OCIE3A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR3 = (1<<OCF3B), TIMSK3 |= (1<<OCIE3B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK3 &= ~(1<<ICIE3))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK3 &= ~(1<<OCIE3A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK3 &= ~(1<<OCIE3B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT3)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR3)
|
||||||
|
#define GET_COMPARE_A() (OCR3A)
|
||||||
|
#define GET_COMPARE_B() (OCR3B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR3A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR3B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER3_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER3_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER3_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_TIMER4)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS40))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS41))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR4A = TCCR4A & ~((1<<COM4A1) | (1<<COM4A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR4A = (TCCR4A & ~(1<<COM4A1)) | (1<<COM4A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR4A = (TCCR4A | (1<<COM4A1)) & ~(1<<COM4A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR4A = TCCR4A | ((1<<COM4A1) | (1<<COM4A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR4B &= ~(1<<ICES4))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR4B |= (1<<ICES4))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR4 = (1<<ICF4), TIMSK4 = (1<<ICIE4))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR4 = (1<<OCF4A), TIMSK4 |= (1<<OCIE4A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR4 = (1<<OCF4B), TIMSK4 |= (1<<OCIE4B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK4 &= ~(1<<ICIE4))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK4 &= ~(1<<OCIE4A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK4 &= ~(1<<OCIE4B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT4)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR4)
|
||||||
|
#define GET_COMPARE_A() (OCR4A)
|
||||||
|
#define GET_COMPARE_B() (OCR4B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR4A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR4B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER4_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER4_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER4_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ALTSS_USE_TIMER5)
|
||||||
|
#define CONFIG_TIMER_NOPRESCALE() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS50))
|
||||||
|
#define CONFIG_TIMER_PRESCALE_8() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS51))
|
||||||
|
#define CONFIG_MATCH_NORMAL() (TCCR5A = TCCR5A & ~((1<<COM5A1) | (1<<COM5A0)))
|
||||||
|
#define CONFIG_MATCH_TOGGLE() (TCCR5A = (TCCR5A & ~(1<<COM5A1)) | (1<<COM5A0))
|
||||||
|
#define CONFIG_MATCH_CLEAR() (TCCR5A = (TCCR5A | (1<<COM5A1)) & ~(1<<COM5A0))
|
||||||
|
#define CONFIG_MATCH_SET() (TCCR5A = TCCR5A | ((1<<COM5A1) | (1<<COM5A0)))
|
||||||
|
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR5B &= ~(1<<ICES5))
|
||||||
|
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR5B |= (1<<ICES5))
|
||||||
|
#define ENABLE_INT_INPUT_CAPTURE() (TIFR5 = (1<<ICF5), TIMSK5 = (1<<ICIE5))
|
||||||
|
#define ENABLE_INT_COMPARE_A() (TIFR5 = (1<<OCF5A), TIMSK5 |= (1<<OCIE5A))
|
||||||
|
#define ENABLE_INT_COMPARE_B() (TIFR5 = (1<<OCF5B), TIMSK5 |= (1<<OCIE5B))
|
||||||
|
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK5 &= ~(1<<ICIE5))
|
||||||
|
#define DISABLE_INT_COMPARE_A() (TIMSK5 &= ~(1<<OCIE5A))
|
||||||
|
#define DISABLE_INT_COMPARE_B() (TIMSK5 &= ~(1<<OCIE5B))
|
||||||
|
#define GET_TIMER_COUNT() (TCNT5)
|
||||||
|
#define GET_INPUT_CAPTURE() (ICR5)
|
||||||
|
#define GET_COMPARE_A() (OCR5A)
|
||||||
|
#define GET_COMPARE_B() (OCR5B)
|
||||||
|
#define SET_COMPARE_A(val) (OCR5A = (val))
|
||||||
|
#define SET_COMPARE_B(val) (OCR5B = (val))
|
||||||
|
#define CAPTURE_INTERRUPT TIMER5_CAPT_vect
|
||||||
|
#define COMPARE_A_INTERRUPT TIMER5_COMPA_vect
|
||||||
|
#define COMPARE_B_INTERRUPT TIMER5_COMPB_vect
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include <AltSoftSerial.h>
|
||||||
|
|
||||||
|
// AltSoftSerial always uses these pins:
|
||||||
|
//
|
||||||
|
// Board Transmit Receive PWM Unusable
|
||||||
|
// ----- -------- ------- ------------
|
||||||
|
// Teensy 3.0 & 3.1 21 20 22
|
||||||
|
// Teensy 2.0 9 10 (none)
|
||||||
|
// Teensy++ 2.0 25 4 26, 27
|
||||||
|
// Arduino Uno 9 8 10
|
||||||
|
// Arduino Leonardo 5 13 (none)
|
||||||
|
// Arduino Mega 46 48 44, 45
|
||||||
|
// Wiring-S 5 6 4
|
||||||
|
// Sanguino 13 14 12
|
||||||
|
|
||||||
|
AltSoftSerial altSerial;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
while (!Serial) ; // wait for Arduino Serial Monitor to open
|
||||||
|
Serial.println("AltSoftSerial Test Begin");
|
||||||
|
altSerial.begin(9600);
|
||||||
|
altSerial.println("Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
char c;
|
||||||
|
|
||||||
|
if (Serial.available()) {
|
||||||
|
c = Serial.read();
|
||||||
|
altSerial.print(c);
|
||||||
|
}
|
||||||
|
if (altSerial.available()) {
|
||||||
|
c = altSerial.read();
|
||||||
|
Serial.print(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
AltSoftSerial KEYWORD1
|
||||||
|
active KEYWORD2
|
||||||
|
overflow KEYWORD2
|
||||||
|
library_version KEYWORD2
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||||
|
* between your home built sensors/actuators and HA controller of choice.
|
||||||
|
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||||
|
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||||
|
* network topology allowing messages to be routed to nodes.
|
||||||
|
*
|
||||||
|
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||||
|
* Copyright (C) 2013-2015 Sensnology AB
|
||||||
|
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||||
|
*
|
||||||
|
* Documentation: http://www.mysensors.org
|
||||||
|
* Support Forum: http://forum.mysensors.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*******************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The RS485 Gateway prints data received from sensors on the serial link.
|
||||||
|
* The gateway accepts input on seral which will be sent out on
|
||||||
|
* the RS485 link.
|
||||||
|
*
|
||||||
|
* Wire connections (OPTIONAL):
|
||||||
|
* - Inclusion button should be connected between digital pin 3 and GND
|
||||||
|
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
|
||||||
|
*
|
||||||
|
* LEDs (OPTIONAL):
|
||||||
|
* - To use the feature, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
|
||||||
|
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||||
|
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||||
|
* - ERR (red) - fast blink on error during transmission error or recieve crc error
|
||||||
|
*
|
||||||
|
* The gateway uses AltSoftSerial to handle two serial links
|
||||||
|
* on one Arduino. Use the following pins for RS485 link
|
||||||
|
*
|
||||||
|
* Board Transmit Receive PWM Unusable
|
||||||
|
* ----- -------- ------- ------------
|
||||||
|
* Teensy 3.0 & 3.1 21 20 22
|
||||||
|
* Teensy 2.0 9 10 (none)
|
||||||
|
* Teensy++ 2.0 25 4 26, 27
|
||||||
|
* Arduino Uno 9 8 10
|
||||||
|
* Arduino Leonardo 5 13 (none)
|
||||||
|
* Arduino Mega 46 48 44, 45
|
||||||
|
* Wiring-S 5 6 4
|
||||||
|
* Sanguino 13 14 12
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Enable debug prints to serial monitor
|
||||||
|
#define MY_DEBUG
|
||||||
|
|
||||||
|
// Enable RS485 transport layer
|
||||||
|
#define MY_RS485
|
||||||
|
|
||||||
|
// Set RS485 baud rate to use
|
||||||
|
#define MY_RS485_BAUD_RATE 9600
|
||||||
|
|
||||||
|
// Enable serial gateway
|
||||||
|
#define MY_GATEWAY_SERIAL
|
||||||
|
|
||||||
|
// Flash leds on rx/tx/err
|
||||||
|
#define MY_LEDS_BLINKING_FEATURE
|
||||||
|
// Set blinking period
|
||||||
|
#define MY_DEFAULT_LED_BLINK_PERIOD 300
|
||||||
|
|
||||||
|
// Enable inclusion mode
|
||||||
|
#define MY_INCLUSION_MODE_FEATURE
|
||||||
|
// Enable Inclusion mode button on gateway
|
||||||
|
#define MY_INCLUSION_BUTTON_FEATURE
|
||||||
|
// Set inclusion mode duration (in seconds)
|
||||||
|
#define MY_INCLUSION_MODE_DURATION 60
|
||||||
|
// Digital pin used for inclusion mode button
|
||||||
|
#define MY_INCLUSION_MODE_BUTTON_PIN 3
|
||||||
|
|
||||||
|
#define MY_DEFAULT_ERR_LED_PIN 7 // Error led pin
|
||||||
|
#define MY_DEFAULT_RX_LED_PIN 8 // Receive led pin
|
||||||
|
#define MY_DEFAULT_TX_LED_PIN 9 // the PCB, on board LED
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <MySensor.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Setup locally attached sensors
|
||||||
|
}
|
||||||
|
|
||||||
|
void presentation() {
|
||||||
|
// Present locally attached sensors
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Send locally attached sensor data here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||||
|
* between your home built sensors/actuators and HA controller of choice.
|
||||||
|
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||||
|
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||||
|
* network topology allowing messages to be routed to nodes.
|
||||||
|
*
|
||||||
|
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||||
|
* Copyright (C) 2013-2015 Sensnology AB
|
||||||
|
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||||
|
*
|
||||||
|
* Documentation: http://www.mysensors.org
|
||||||
|
* Support Forum: http://forum.mysensors.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*******************************
|
||||||
|
*
|
||||||
|
* REVISION HISTORY
|
||||||
|
* Version 1.0 - Henrik Ekblad
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* This is an example of sensors using RS485 as transport layer
|
||||||
|
*
|
||||||
|
* Motion Sensor example using HC-SR501
|
||||||
|
* http://www.mysensors.org/build/motion
|
||||||
|
*
|
||||||
|
* The transport uses AltSoftSerial to handle two serial links
|
||||||
|
* on one Arduino. Use the following pins for RS485 link
|
||||||
|
*
|
||||||
|
* Board Transmit Receive PWM Unusable
|
||||||
|
* ----- -------- ------- ------------
|
||||||
|
* Teensy 3.0 & 3.1 21 20 22
|
||||||
|
* Teensy 2.0 9 10 (none)
|
||||||
|
* Teensy++ 2.0 25 4 26, 27
|
||||||
|
* Arduino Uno 9 8 10
|
||||||
|
* Arduino Leonardo 5 13 (none)
|
||||||
|
* Arduino Mega 46 48 44, 45
|
||||||
|
* Wiring-S 5 6 4
|
||||||
|
* Sanguino 13 14 12 *
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Enable RS485 transport layer
|
||||||
|
#define MY_RS485
|
||||||
|
|
||||||
|
// Set RS485 baud rate to use
|
||||||
|
#define MY_RS485_BAUD_RATE 9600
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <MySensor.h>
|
||||||
|
|
||||||
|
unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
|
||||||
|
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
|
||||||
|
#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
|
||||||
|
#define CHILD_ID 1 // Id of the sensor child
|
||||||
|
|
||||||
|
// Initialize motion message
|
||||||
|
MyMessage msg(CHILD_ID, V_TRIPPED);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||||
|
}
|
||||||
|
|
||||||
|
void presentation() {
|
||||||
|
// Send the sketch version information to the gateway and Controller
|
||||||
|
sendSketchInfo("Motion Sensor", "1.0");
|
||||||
|
|
||||||
|
// Register all sensors to gw (they will be created as child devices)
|
||||||
|
present(CHILD_ID, S_MOTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// Read digital motion value
|
||||||
|
boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
||||||
|
|
||||||
|
Serial.println(tripped);
|
||||||
|
send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||||
|
|
||||||
|
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
|
||||||
|
sleep(INTERRUPT,CHANGE, SLEEP_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
|
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
|
||||||
// example for more information on possible values.
|
// example for more information on possible values.
|
||||||
|
|
||||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEO_PIN, NEO_GRB + NEO_KHZ400);
|
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEO_PIN, NEO_GRB + NEO_KHZ800);
|
||||||
|
|
||||||
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
||||||
|
|
||||||
@@ -107,7 +107,6 @@ void presentation() {
|
|||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
|
||||||
unsigned int fullDist = (sonar.ping_median() / US_ROUNDTRIP_CM);
|
unsigned int fullDist = (sonar.ping_median() / US_ROUNDTRIP_CM);
|
||||||
// Serial.println(fullDist);
|
// Serial.println(fullDist);
|
||||||
int displayDist = min(fullDist, MAX_DISTANCE);
|
int displayDist = min(fullDist, MAX_DISTANCE);
|
||||||
|
|||||||
@@ -96,3 +96,6 @@ MY_ESP8266_PASSWORD LITERAL1
|
|||||||
MY_IP_GATEWAY_ADDRESS LITERAL1
|
MY_IP_GATEWAY_ADDRESS LITERAL1
|
||||||
MY_IP_SUBNET_ADDRESS LITERAL1
|
MY_IP_SUBNET_ADDRESS LITERAL1
|
||||||
MY_W5100_SPI_EN LITERAL1
|
MY_W5100_SPI_EN LITERAL1
|
||||||
|
MY_RS485 LITERAL1
|
||||||
|
MY_RS485_BAUD_RATE LITERAL1
|
||||||
|
MY_RS485_MAX_MESSAGE_LENGTH LITERAL1
|
||||||
Reference in New Issue
Block a user