mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-09-17 17:32:25 -07:00
added updated tinypinchange and associated libraries to support PRO
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
English: by RC Navy (2012)
|
||||
=======
|
||||
<SoftRcPulseIn>: an asynchronous library to read Input Pulse Width from standard Hobby Radio-Control. This library is a non-blocking version of pulseIn().
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
Francais: par RC Navy (2012)
|
||||
========
|
||||
<SoftRcPulseIn>: une librairie asynchrone pour lire les largeur d'impulsions des Radio-Commandes standards. Cette librairie est une version non bloquante de pulsIn().
|
||||
http://p.loussouarn.free.fr
|
||||
*/
|
||||
|
||||
#include "SoftRcPulseIn.h"
|
||||
|
||||
#define LIB_VERSION 1
|
||||
#define LIB_REVISION 0
|
||||
|
||||
#define STR(s) #s
|
||||
#define MAKE_TEXT_VER_REV(Ver,Rev) STR(Ver)"."STR(Rev)
|
||||
|
||||
#define LIB_TEXT_VERSION_REVISION MAKE_TEXT_VER_REV(LIB_VERSION,LIB_REVISION) /* Make Full version as a string "Ver.Rev" */
|
||||
|
||||
SoftRcPulseIn *SoftRcPulseIn::first;
|
||||
|
||||
SoftRcPulseIn::SoftRcPulseIn(void)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseIn::attach(uint8_t Pin, uint16_t PulseMin_us/*=600*/, uint16_t PulseMax_us/*=2400*/)
|
||||
{
|
||||
uint8_t Ret=0;
|
||||
|
||||
_Pin=Pin;
|
||||
_PinMask=TinyPinChange_PinToMsk(Pin);
|
||||
_Min_us=PulseMin_us;
|
||||
_Max_us=PulseMax_us;
|
||||
next = first;
|
||||
first = this;
|
||||
pinMode(_Pin,INPUT);
|
||||
digitalWrite(_Pin, HIGH);
|
||||
_VirtualPortIdx=TinyPinChange_RegisterIsr(_Pin,SoftRcPulseIn::SoftRcPulseInInterrupt);
|
||||
if(_VirtualPortIdx>=0)
|
||||
{
|
||||
TinyPinChange_EnablePin(_Pin);
|
||||
Ret=1;
|
||||
}
|
||||
return(Ret);
|
||||
}
|
||||
|
||||
int SoftRcPulseIn::LibVersion(void)
|
||||
{
|
||||
return(LIB_VERSION);
|
||||
}
|
||||
|
||||
int SoftRcPulseIn::LibRevision(void)
|
||||
{
|
||||
return(LIB_REVISION);
|
||||
}
|
||||
|
||||
char *SoftRcPulseIn::LibTextVersionRevision(void)
|
||||
{
|
||||
return(LIB_TEXT_VERSION_REVISION);
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseIn::available(void)
|
||||
{
|
||||
boolean Ret=0;
|
||||
uint16_t PulseWidth_us;
|
||||
|
||||
if(_Available)
|
||||
{
|
||||
noInterrupts();
|
||||
PulseWidth_us=_Width_us;
|
||||
interrupts();
|
||||
Ret=_Available && (PulseWidth_us>=_Min_us) && (PulseWidth_us<=_Max_us);
|
||||
_Available=0;
|
||||
}
|
||||
return(Ret);
|
||||
}
|
||||
|
||||
uint16_t SoftRcPulseIn::width_us(void)
|
||||
{
|
||||
uint16_t PulseWidth_us;
|
||||
noInterrupts();
|
||||
PulseWidth_us=_Width_us;
|
||||
interrupts();
|
||||
return(PulseWidth_us);
|
||||
}
|
||||
|
||||
void SoftRcPulseIn::SoftRcPulseInInterrupt(void)
|
||||
{
|
||||
SoftRcPulseIn *RcPulseIn;
|
||||
|
||||
for ( RcPulseIn = first; RcPulseIn != 0; RcPulseIn = RcPulseIn->next )
|
||||
{
|
||||
if(TinyPinChange_GetPortEvent(RcPulseIn->_VirtualPortIdx)&RcPulseIn->_PinMask)
|
||||
{
|
||||
if(digitalRead(RcPulseIn->_Pin))
|
||||
{
|
||||
/* High level, rising edge: start chrono */
|
||||
RcPulseIn->_Start_us=micros();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Low level, falling edge: stop chrono */
|
||||
RcPulseIn->_Width_us=micros()-RcPulseIn->_Start_us;
|
||||
RcPulseIn->_Available=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
English: by RC Navy (2012)
|
||||
=======
|
||||
<SoftRcPulseIn>: an asynchronous library to read Input Pulse Width from standard Hobby Radio-Control. This library is a non-blocking version of pulseIn().
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
Francais: par RC Navy (2012)
|
||||
========
|
||||
<SoftRcPulseIn>: une librairie asynchrone pour lire les largeur d'impulsions des Radio-Commandes standards. Cette librairie est une version non bloquante de pulsIn().
|
||||
http://p.loussouarn.free.fr
|
||||
*/
|
||||
|
||||
#ifndef SOFT_RC_PULSE_IN_H
|
||||
#define SOFT_RC_PULSE_IN_H
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <TinyPinChange.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
class SoftRcPulseIn
|
||||
{
|
||||
public:
|
||||
SoftRcPulseIn();
|
||||
static int LibVersion(void);
|
||||
static int LibRevision(void);
|
||||
static char *LibTextVersionRevision(void);
|
||||
static void SoftRcPulseInInterrupt(void);
|
||||
uint8_t attach(uint8_t Pin, uint16_t PulseMin_us=600, uint16_t PulseMax_us=2400);
|
||||
boolean available();
|
||||
uint16_t width_us();
|
||||
private:
|
||||
class SoftRcPulseIn *next;
|
||||
static SoftRcPulseIn *first;
|
||||
uint8_t _Pin;
|
||||
uint8_t _PinMask;
|
||||
uint8_t _VirtualPortIdx;
|
||||
uint16_t _Min_us;
|
||||
uint16_t _Max_us;
|
||||
uint32_t _Start_us;
|
||||
uint32_t _Width_us;
|
||||
boolean _Available;
|
||||
};
|
||||
/*******************************************************/
|
||||
/* Application Programming Interface (API) en Francais */
|
||||
/*******************************************************/
|
||||
|
||||
/* Methodes en Francais English native methods */
|
||||
#define attache attach
|
||||
#define disponible available
|
||||
#define largeur_us width_us
|
||||
|
||||
#endif
|
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| |_| \____/ |_| \__| |_| |_| \__/ |_| 2013
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
*******************************************
|
||||
* Digispark RC Debug Demo with 1 I/O *
|
||||
*******************************************
|
||||
|
||||
This sketch demonstrates how to display received RC pulse width with a Digispark in the serial console of the arduino IDE.
|
||||
by using a bi-directional serial port using a single I/O.
|
||||
This approach allows to use the built-in Serial Console of the arduino IDE.
|
||||
Please, note this solution requires a native RS232 port (rare today) or a RS232/USB adapter on the development PC.
|
||||
|
||||
To display properly the outputs in the IDE serial console, you have to:
|
||||
- in the arduino IDE, select "Tools->Board->Digispark 16.0mhz - NO USB (Tiny core)"
|
||||
- in the arduino IDE, select the right serial port in "Tools->Serial Port" and select the port where the debug cable is connected to.
|
||||
- in the serial console, set the right baud rate (38400 in this sketch)
|
||||
|
||||
In this sketch, only Tx capabilty of SoftSerial is used.
|
||||
|
||||
Hardware Wiring:
|
||||
===============
|
||||
SERIAL SINGLE I/O
|
||||
DEBUGGING CABLE
|
||||
___________________/\__________________
|
||||
/ \
|
||||
____
|
||||
.--------. | \
|
||||
| GND |--------------------------------+---o5 \
|
||||
| | 47K | | 9o |
|
||||
| | .--###--' | o4 |
|
||||
| DEBUG | 4.7K | | 8o |
|
||||
| TX_RX |-------------------###--+--|<|------o3 | ---> To regular RS232 SubD 9 pins Male of PC
|
||||
| PIN | ^ | 1N4148 | 7o | or to RS232/USB adapter
|
||||
| | | '-----------o2 |
|
||||
'--------' | | 6o |
|
||||
ATtiny85 Single | o1 /
|
||||
(Digispark) I/O |____/
|
||||
SubD 9 pins
|
||||
Female
|
||||
*/
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftRcPulseIn.h>
|
||||
#include <SoftSerial.h>
|
||||
|
||||
#define RX_AUX_GEAR_PIN 0 //Choose here the pin for the RC signal
|
||||
#define DEBUG_TX_RX_PIN 1 //Adjust here your Tx/Rx debug pin (Do NOT work on Digispark PIN 5: choose another PIN)
|
||||
|
||||
SoftRcPulseIn RxAuxGear; //Choose a name for your RC channel signal
|
||||
|
||||
SoftSerial MyDbgSerial(DEBUG_TX_RX_PIN, DEBUG_TX_RX_PIN, true); //true allows to connect to a regular RS232 without RS232 line driver
|
||||
|
||||
void setup()
|
||||
{
|
||||
RxAuxGear.attach(RX_AUX_GEAR_PIN);
|
||||
|
||||
MyDbgSerial.begin(38400); //Do NOT forget to setup your terminal at 38400 (eg: arduino IDE serial monitor)
|
||||
MyDbgSerial.txMode(); //Before sending a message, switch to txMode
|
||||
MyDbgSerial.print(F("SoftRcPulseIn lib V"));MyDbgSerial.print(SoftRcPulseIn::LibTextVersionRevision());MyDbgSerial.println(F(" demo"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if(RxAuxGear.available())
|
||||
{
|
||||
MyDbgSerial.print(F("Pulse="));MyDbgSerial.println(RxAuxGear.width_us()); // Display Rx Pulse Width (in us)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,28 @@
|
||||
#include <SoftRcPulseIn.h>
|
||||
#include <TinyPinChange.h>
|
||||
|
||||
#define BROCHE_VOIE1 2
|
||||
|
||||
SoftRcPulseIn ImpulsionVoie1;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__)
|
||||
Serial.begin(9600);
|
||||
Serial.print("SoftRcPulseIn library V");Serial.print(SoftRcPulseIn::LibTextVersionRevision());Serial.print(" demo");
|
||||
#endif
|
||||
ImpulsionVoie1.attache(BROCHE_VOIE1);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if(ImpulsionVoie1.disponible())
|
||||
{
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__)
|
||||
Serial.print("Pulse=");Serial.println(ImpulsionVoie1.largeur_us());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
This sketch demonstrates how to use <SoftRcPulseIn> library to get RC pulses from a receiver and to use <SoftRcPulseOut> library to drive 2 servos.
|
||||
The first servo will follow the order, and the second one will have a reverted motion.
|
||||
Please notice this sketch is fully asynchronous: no blocking functions such as delay() or pulseIn() are used.
|
||||
Tested on arduino UNO, ATtiny84, ATtiny85 and Digispark rev2 (Model A).
|
||||
RC Navy 2013
|
||||
http://p.loussouarn.free.fr
|
||||
*/
|
||||
|
||||
#include <SoftRcPulseIn.h>
|
||||
#include <SoftRcPulseOut.h>
|
||||
#include <TinyPinChange.h> /* Needed for <SoftRcPulseIn> library */
|
||||
|
||||
#define RX_CHANNEL_PIN 2
|
||||
|
||||
#define SERVO1_PIN 3
|
||||
#define SERVO2_PIN 4
|
||||
|
||||
#define LED_PIN 1//1 on Digispark rev2 (Model A), change to pin 0 for Digispark rev1 (Model B), change to 13 for UNO
|
||||
|
||||
#define LED_HALF_PERIOD_MS 250
|
||||
|
||||
#define PULSE_MAX_PERIOD_MS 30 /* To refresh the servo in case of pulse extinction */
|
||||
|
||||
#define NOW 1
|
||||
|
||||
#define NEUTRAL_US 1500 /* Default position in case of no pulse at startup */
|
||||
|
||||
enum {NORMAL=0, INVERTED, SERVO_NB}; /* Trick: use an enumeration to declare the index of the servos AND the amount of servos */
|
||||
|
||||
|
||||
SoftRcPulseIn RxChannelPulse; /* RxChannelPulse is an objet of SoftRcPulseIn type */
|
||||
SoftRcPulseOut ServoMotor[SERVO_NB]; /* Table Creation for 2 objets of SoftRcPulseOut type */
|
||||
|
||||
/* Possible values to compute a shifting average fin order to smooth the recieved pulse witdh */
|
||||
#define AVG_WITH_1_VALUE 0
|
||||
#define AVG_WITH_2_VALUES 1
|
||||
#define AVG_WITH_4_VALUES 2
|
||||
#define AVG_WITH_8_VALUES 3
|
||||
#define AVG_WITH_16_VALUES 4
|
||||
|
||||
#define AVERAGE_LEVEL AVG_WITH_4_VALUES /* Choose here the average level among the above listed values */
|
||||
/* Higher is the average level, more the system is stable (jitter suppression), but lesser is the reaction */
|
||||
|
||||
/* Macro for average */
|
||||
#define AVERAGE(ValueToAverage,LastReceivedValue,AverageLevelInPowerOf2) ValueToAverage=(((ValueToAverage)*((1<<(AverageLevelInPowerOf2))-1)+(LastReceivedValue))/(1<<(AverageLevelInPowerOf2)))
|
||||
|
||||
/* Variables */
|
||||
uint32_t LedStartMs=millis();
|
||||
uint32_t RxPulseStartMs=millis();
|
||||
boolean LedState=HIGH;
|
||||
|
||||
void setup()
|
||||
{
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__)
|
||||
Serial.begin(9600);
|
||||
Serial.print("SoftRcPulseIn library V");Serial.print(SoftRcPulseIn::LibTextVersionRevision());Serial.print(" demo"); /* For arduino UNO which has an hardware UART, display the library version in the console */
|
||||
#endif
|
||||
RxChannelPulse.attach(RX_CHANNEL_PIN);
|
||||
ServoMotor[NORMAL].attach(SERVO1_PIN); /* enumeration is used a index for the ServoMotor[] table */
|
||||
ServoMotor[INVERTED].attach(SERVO2_PIN); /* enumeration is used a index for the ServoMotor[]table */
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static uint16_t Width_us=NEUTRAL_US; /* Static to keep the value at the next loop */
|
||||
|
||||
/* Receiver pulse acquisition and command of 2 servos, one in the direct direction, one in the inverted direction */
|
||||
if(RxChannelPulse.available())
|
||||
{
|
||||
AVERAGE(Width_us,RxChannelPulse.width_us(),AVERAGE_LEVEL);
|
||||
ServoMotor[NORMAL].write_us(Width_us); /* Direct Signal */
|
||||
ServoMotor[INVERTED].write_us((NEUTRAL_US*2)-Width_us); /* Inverted Signal */
|
||||
SoftRcPulseOut::refresh(NOW); /* NOW argument (=1) allows to synchronize outgoing pulses with incoming pulses */
|
||||
RxPulseStartMs=millis(); /* Restart the Chrono for Pulse */
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__)
|
||||
Serial.print("Pulse=");Serial.println(Largeur_us); /* For arduino UNO which has an hardware UART, display the library version in the console */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for pulse extinction */
|
||||
if(millis()-RxPulseStartMs>=PULSE_MAX_PERIOD_MS)
|
||||
{
|
||||
/* Refresh the servos with the last known position in order to avoid "flabby" servos */
|
||||
SoftRcPulseOut::refresh(NOW); /* Immediate refresh of outgoing pulses */
|
||||
RxPulseStartMs=millis(); /* Restart the Chrono for Pulse */
|
||||
}
|
||||
}
|
||||
|
||||
/* Blink LED Management */
|
||||
if(millis()-LedStartMs>=LED_HALF_PERIOD_MS)
|
||||
{
|
||||
digitalWrite(LED_PIN, LedState);
|
||||
LedState=!LedState; /* At the next loop, if the half period is elapsed, the LED state will be inverted */
|
||||
LedStartMs=millis(); /* Restart the Chrono for the LED */
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map SoftRcPulseIn
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
SoftRcPulseIn KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
LibVersion KEYWORD2
|
||||
LibRevision KEYWORD2
|
||||
LibTextVersionRevision KEYWORD2
|
||||
attach KEYWORD2
|
||||
attache KEYWORD2
|
||||
available KEYWORD2
|
||||
disponible KEYWORD2
|
||||
width_us KEYWORD2
|
||||
largeur_us KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
Reference in New Issue
Block a user