mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-09-17 09:22:28 -07:00
added updated tinypinchange and associated libraries to support PRO
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
/********************************************************************************/
|
||||
/* PROJECT: All based on ATtinyX5, ATtinyX4, Atiny167, ATmega328P, ATmega2560 */
|
||||
/* MODULE: TinyPinChange */
|
||||
/* VERSION: 1.2 (20/12/2014) */
|
||||
/* DATE: 30/01/2011 */
|
||||
/* TARGET: ATtinyX5, ATtinyX4, ATtiny167, ATmega328P, ATmega2560 */
|
||||
/* COMPILER: WinAvr, avr-gcc, avr-g++ */
|
||||
/* IDE: ARDUINO, AVR Studio 4 */
|
||||
/* PROGRAMER: AVR-JTAG-ICE MKII, ARDUINO IDE */
|
||||
/* AUTHOR: P.LOUSSOUARN (P.Loussouarn: http://p.loussouarn.free.fr) */
|
||||
/********************************************************************************/
|
||||
#include <TinyPinChange.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
/*************************************************************************
|
||||
MACROS
|
||||
*************************************************************************/
|
||||
|
||||
#define PIN_CHANGE_HANDLER_MAX_NB 3 /* ISR max number Pin Change ISR can handle per port */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
GLOBAL VARIABLES
|
||||
*************************************************************************/
|
||||
struct PinChangeStruct
|
||||
{
|
||||
void (*Isr[PIN_CHANGE_HANDLER_MAX_NB])(void);
|
||||
uint8_t LoadedIsrNb;
|
||||
uint8_t Event;
|
||||
uint8_t PinPrev;
|
||||
uint8_t PinCur;
|
||||
};
|
||||
|
||||
struct PinChangePortStruct
|
||||
{
|
||||
PinChangeStruct Port[PIN_CHG_PORT_NB];
|
||||
};
|
||||
|
||||
static volatile struct PinChangePortStruct PinChange;
|
||||
|
||||
/*************************************************************************
|
||||
INTERRUPT SUB-ROUTINE
|
||||
*************************************************************************/
|
||||
#define DECLARE_PIN_CHANGE_ISR(VirtualPortIdx) \
|
||||
ISR(PCINT##VirtualPortIdx##_vect) \
|
||||
{ \
|
||||
uint8_t Idx; \
|
||||
PinChange.Port[VirtualPortIdx].PinCur = (PC_PIN##VirtualPortIdx) & (PC_PCMSK##VirtualPortIdx); \
|
||||
PinChange.Port[VirtualPortIdx].Event = PinChange.Port[VirtualPortIdx].PinPrev ^ PinChange.Port[VirtualPortIdx].PinCur; \
|
||||
PinChange.Port[VirtualPortIdx].PinPrev = PinChange.Port[VirtualPortIdx].PinCur; \
|
||||
for(Idx = 0; Idx < PinChange.Port[VirtualPortIdx].LoadedIsrNb; Idx++) \
|
||||
{ \
|
||||
PinChange.Port[VirtualPortIdx].Isr[Idx](); \
|
||||
} \
|
||||
}
|
||||
|
||||
DECLARE_PIN_CHANGE_ISR(0)
|
||||
|
||||
#if defined(__AVR_ATtinyX4__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__)
|
||||
DECLARE_PIN_CHANGE_ISR(1)
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__)
|
||||
DECLARE_PIN_CHANGE_ISR(2)
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
PUBLIC FUNCTIONS
|
||||
*************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
PinChange Initialization Function
|
||||
Input:
|
||||
Void
|
||||
Output:
|
||||
Void
|
||||
*********************************************************************/
|
||||
void TinyPinChange_Init(void)
|
||||
{
|
||||
/* ATtinyX5, ATtiny167, ATtinyX4, UNO, MEGA */
|
||||
PinChange.Port[0].PinCur = PC_PIN0 & PC_PCMSK0;//PINB for ATtinyX5, UNO or MEGA, PINA for ATtinyX4 or ATtiny167
|
||||
PinChange.Port[0].PinPrev = PinChange.Port[0].PinCur;
|
||||
#if defined(__AVR_ATtinyX4__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__)
|
||||
/* ATtinyX4, ATtiny167, UNO or MEGA */
|
||||
PinChange.Port[1].PinCur = PC_PIN1 & PC_PCMSK1;//PINB for for ATtinyX4 or ATtiny167, PINC for UNO, PINJ for MEGA
|
||||
PinChange.Port[1].PinPrev = PinChange.Port[1].PinCur;
|
||||
#endif
|
||||
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__)
|
||||
/* UNO or MEGA */
|
||||
PinChange.Port[2].PinCur = PC_PIN2 & PC_PCMSK2;//PIND for UNO, PINK for MEGA
|
||||
PinChange.Port[2].PinPrev = PinChange.Port[2].PinCur;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
PinChange RegisterIsr Function
|
||||
Input:
|
||||
Pointer on a PinChange Function
|
||||
Output:
|
||||
The associated VirtualPortIdx (0 to 2)
|
||||
< 0 in case of failure
|
||||
*********************************************************************/
|
||||
int8_t TinyPinChange_RegisterIsr(uint8_t Pin, void(*Isr)(void))
|
||||
{
|
||||
int8_t IsrIdx, PortIdx, AlreadyLoaded = 0;
|
||||
|
||||
PortIdx = DigitalPinToPortIdx(Pin);
|
||||
|
||||
for(IsrIdx = 0; IsrIdx < PIN_CHANGE_HANDLER_MAX_NB; IsrIdx++)
|
||||
{
|
||||
if(PinChange.Port[PortIdx].Isr[IsrIdx] == Isr)
|
||||
{
|
||||
AlreadyLoaded = 1;
|
||||
break; /* Already loaded */
|
||||
}
|
||||
}
|
||||
|
||||
if(!AlreadyLoaded)
|
||||
{
|
||||
if(PinChange.Port[PortIdx].LoadedIsrNb < PIN_CHANGE_HANDLER_MAX_NB)
|
||||
{
|
||||
/* Not aready loaded: load it */
|
||||
PinChange.Port[PortIdx].Isr[PinChange.Port[PortIdx].LoadedIsrNb] = Isr;
|
||||
PinChange.Port[PortIdx].LoadedIsrNb++;
|
||||
}
|
||||
else PortIdx = -1; /* Failure */
|
||||
}
|
||||
return(PortIdx);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
PinChange Enable Pin Function
|
||||
Input:
|
||||
Pin: the Pin
|
||||
Output:
|
||||
Void
|
||||
*********************************************************************/
|
||||
void TinyPinChange_EnablePin(uint8_t Pin)
|
||||
{
|
||||
if(digitalPinToPCICR(Pin))
|
||||
{
|
||||
*digitalPinToPCICR(Pin) |= _BV(digitalPinToPCICRbit(Pin));
|
||||
*digitalPinToPCMSK(Pin) |= _BV(digitalPinToPCMSKbit(Pin));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
PinChange Disable Pin Function
|
||||
Input:
|
||||
Pin: the Pin
|
||||
Output:
|
||||
Void
|
||||
*********************************************************************/
|
||||
void TinyPinChange_DisablePin(uint8_t Pin)
|
||||
{
|
||||
if(digitalPinToPCICR(Pin))
|
||||
{
|
||||
*digitalPinToPCMSK(Pin) &= (_BV(digitalPinToPCMSKbit(Pin)) ^ 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
PinChange GetPortEvent Function
|
||||
Input:
|
||||
VirtualPortIdx: Index of the Port
|
||||
Output:
|
||||
The bits which have changed in the port
|
||||
*********************************************************************/
|
||||
uint8_t TinyPinChange_GetPortEvent(uint8_t VirtualPortIdx)
|
||||
{
|
||||
return(PinChange.Port[VirtualPortIdx].Event);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
PinChange GetCurPortSt Function
|
||||
Input:
|
||||
VirtualPortIdx: Index of the Port
|
||||
Output:
|
||||
Current Status of the port
|
||||
*********************************************************************/
|
||||
uint8_t TinyPinChange_GetCurPortSt(uint8_t VirtualPortIdx)
|
||||
{
|
||||
return(PinChange.Port[VirtualPortIdx].PinCur);
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
#ifndef TINY_PIN_CHANGE_H
|
||||
#define TINY_PIN_CHANGE_H 1
|
||||
|
||||
/*
|
||||
* <TinyPinChange>, a library for Pin Change Interrupt by RC Navy (2012)
|
||||
* Supported devices: ATmega238P (UNO), ATmega2560 (MEGA), ATtiny84, ATtiny85, ATtiny167
|
||||
*
|
||||
* http://p.loussouarn.free.fr
|
||||
* 20/04/2014: Support for MEGA added
|
||||
* 22/12/2014: Support for ATtiny167 added
|
||||
* Methods TinyPinChange_Edge(), TinyPinChange_RisingEdge(), TinyPinChange_FallingEdge() added
|
||||
* TinyPinChange_GetPinEvent() replaced with TinyPinChange_GetPortEvent()
|
||||
* TinyPinChange_GetPinCurSt() replaced with TinyPinChange_GetCurPortSt()
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __AVR_ATtinyX5__
|
||||
#undef __AVR_ATtinyX5__
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
#define __AVR_ATtinyX5__
|
||||
#endif
|
||||
|
||||
#ifdef __AVR_ATtinyX4__
|
||||
#undef __AVR_ATtinyX4__
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
#define __AVR_ATtinyX4__
|
||||
#endif
|
||||
|
||||
#ifdef __AVR_ATtinyX5__
|
||||
/* ATtinyX5 */
|
||||
#define PIN_CHG_PORT_NB 1
|
||||
#define DigitalPinToPortIdx(p) 0
|
||||
#define PC_PIN0 PINB
|
||||
#define PC_PCMSK0 PCMSK
|
||||
#else
|
||||
#ifdef __AVR_ATtinyX4__
|
||||
/* ATtinyX4 */
|
||||
#define PIN_CHG_PORT_NB 2
|
||||
#define DigitalPinToPortIdx(p) (((p) <= 7) ? (0) : (((p) <= 10) ? (1) : (0)))
|
||||
#define PC_PIN0 PINA
|
||||
#define PC_PCMSK0 PCMSK0
|
||||
#define PC_PIN1 PINB
|
||||
#define PC_PCMSK1 PCMSK1
|
||||
#else
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
/* MEGA */
|
||||
#define PIN_CHG_PORT_NB 3
|
||||
#define DigitalPinToPortIdx(p) ((((p) >= A8) && ((p) <= A15)) ? (2) : ((((p) >= 50) && ((p) <= 53)) ? (0) : ((((p) >= 10) && ((p) <= 13)) ? (0) : (1))))
|
||||
#define PC_PIN0 PINB
|
||||
#define PC_PCMSK0 PCMSK0
|
||||
#define PC_PIN1 PINJ
|
||||
#define PC_PCMSK1 PCMSK1
|
||||
#define PC_PIN2 PINK
|
||||
#define PC_PCMSK2 PCMSK2
|
||||
#else
|
||||
#if defined(__AVR_ATtiny167__)
|
||||
/* ATtiny167 */
|
||||
#define PIN_CHG_PORT_NB 2
|
||||
#define DigitalPinToPortIdx(p) (((p) >= 5 && (p) <= 12) ? (0) : (1))
|
||||
#define PC_PIN0 PINA
|
||||
#define PC_PCMSK0 PCMSK0
|
||||
#define PC_PIN1 PINB
|
||||
#define PC_PCMSK1 PCMSK1
|
||||
#else
|
||||
/* UNO */
|
||||
#define PIN_CHG_PORT_NB 3
|
||||
#define DigitalPinToPortIdx(p) (((p) <= 7) ? (2) : (((p) <= 13) ? (0) : (((p) <= 21) ? (1) : (0))))
|
||||
#define PC_PIN0 PINB
|
||||
#define PC_PCMSK0 PCMSK0
|
||||
#define PC_PIN1 PINC
|
||||
#define PC_PCMSK1 PCMSK1
|
||||
#define PC_PIN2 PIND
|
||||
#define PC_PCMSK2 PCMSK2
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void TinyPinChange_Init(void);
|
||||
int8_t TinyPinChange_RegisterIsr(uint8_t Pin, void(*Isr)(void));
|
||||
void TinyPinChange_EnablePin(uint8_t Pin);
|
||||
void TinyPinChange_DisablePin(uint8_t Pin);
|
||||
uint8_t TinyPinChange_GetPortEvent(uint8_t VirtualPortIdx);
|
||||
uint8_t TinyPinChange_GetCurPortSt(uint8_t VirtualPortIdx);
|
||||
#define TinyPinChange_PinToMsk(Pin) _BV(digitalPinToPCMSKbit(Pin))
|
||||
#define TinyPinChange_Edge(VirtualPortIdx, Pin) ( TinyPinChange_GetPortEvent((VirtualPortIdx)) & TinyPinChange_PinToMsk((Pin)) )
|
||||
#define TinyPinChange_RisingEdge(VirtualPortIdx, Pin) ( TinyPinChange_GetPortEvent((VirtualPortIdx)) & TinyPinChange_PinToMsk((Pin)) & TinyPinChange_GetCurPortSt((VirtualPortIdx)) )
|
||||
#define TinyPinChange_FallingEdge(VirtualPortIdx, Pin) ( TinyPinChange_GetPortEvent((VirtualPortIdx)) & TinyPinChange_PinToMsk((Pin)) & (TinyPinChange_GetCurPortSt((VirtualPortIdx) ^ 0xFF)) )
|
||||
|
||||
/*******************************************************/
|
||||
/* Application Programming Interface (API) en Francais */
|
||||
/*******************************************************/
|
||||
|
||||
/* Methodes en Francais English native methods */
|
||||
#define TinyPinChange_EnregistreFonctionInterruption TinyPinChange_RegisterIsr
|
||||
#define TinyPinChange_ActiveBroche TinyPinChange_EnablePin
|
||||
#define TinyPinChange_DesactiveBroche TinyPinChange_DisablePin
|
||||
#define TinyPinChange_RetourneEvenemenPort TinyPinChange_GetPortEvent
|
||||
#define TinyPinChange_RetourneEtatCourantPort TinyPinChange_GetCurPortSt
|
||||
#define TinyPinChange_MasqueDeBroche TinyPinChange_PinToMsk
|
||||
#define TinyPinChange_Front TinyPinChange_Edge
|
||||
#define TinyPinChange_FrontMontant TinyPinChange_RisingEdge
|
||||
#define TinyPinChange_FrontDescendant TinyPinChange_FallingEdge
|
||||
|
||||
#endif
|
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2013/2014
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
*******************************************************
|
||||
* <TinyPinChange> library Demo *
|
||||
* with debugging capabilities using *
|
||||
* <SoftSerial> object as single wire serial interface *
|
||||
*******************************************************
|
||||
|
||||
This sketch demonstrates how to use <TinyPinChange> library.
|
||||
It counts all the transitions (both edges) on 2 different pins.
|
||||
/!\CAUTION/!\: as <TinyPinChange> library can be shared (and it is with SoftSerial in this sketch) , the user shall test if the changes are related to the declared pins.
|
||||
|
||||
Trick: By connecting Pin#1 to Pin#0 or to Pin#5 through a 1K resistor, you can generate transitions for testing purpose.
|
||||
Output results are sent to a software serial.
|
||||
|
||||
And the great thing is: using a <SoftSerial> object as a bi-directionnal software serial port (half-duplex) on a single pin to communicate with the outside world!
|
||||
|
||||
To display the sketch results on a PC (in a Terminal):
|
||||
1) Build the "Serial One Wire Debug Cable" and plug it to the regular RS232 port as depicted below,
|
||||
2) Open your favorite Terminal at 38400,n,8,1: HyperTerminal, Teraterm (Windows) or Minicom, GtkTerm (Linux) and CoolTerm (MAC) does the trick.
|
||||
3) You can also use the Serial Monitor of the arduino IDE: Tools->Serial Port and select your RS232 port (may be an USB virtual port), Rate=38400.
|
||||
4) To enable the display, type 1, to disable, type 0 in the Terminal/Monitor.
|
||||
|
||||
SERIAL ONE WIRE
|
||||
DEBUGGING CABLE
|
||||
_______________ ________________
|
||||
/ \___/\___/ \
|
||||
____
|
||||
.--------. | \
|
||||
| GND |--------------------------------+---o5 \
|
||||
| | 47K | | 9o |
|
||||
| | .--###--' | o4 |
|
||||
| DEBUG | 4.7K | | 8o |
|
||||
| TX_RX |-------------------###--+--|<|------o3 | ---> To regular RS232 SubD 9 pins Male of PC or Serial/USB adapter
|
||||
| PIN | ^ | 1N4148 | 7o |
|
||||
| | | '-----------o2 |
|
||||
'--------' | | 6o |
|
||||
ATtiny85 Single | o1 /
|
||||
(Digispark) I/O |____/
|
||||
SubD 9 pins
|
||||
Female
|
||||
*/
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftSerial.h>
|
||||
|
||||
#define LED_PIN 1
|
||||
|
||||
#define DEBUG_TX_RX_PIN 2
|
||||
|
||||
#define FIRST_INPUT 0
|
||||
#define SECOND_INPUT 5
|
||||
|
||||
volatile uint16_t FirstInputChangeCount = 0; /* Volatile since the variable will be updated in interruption */
|
||||
volatile uint16_t SecondInputChangeCount = 0; /* Volatile since the variable will be updated in interruption */
|
||||
|
||||
SoftSerial MySerial(DEBUG_TX_RX_PIN, DEBUG_TX_RX_PIN, true); /* Tx/Rx on a single Pin !!! (Pin#2) */
|
||||
|
||||
uint8_t VirtualPortNb;
|
||||
uint8_t VirtualPortNb_;
|
||||
|
||||
void setup()
|
||||
{
|
||||
TinyPinChange_Init();
|
||||
|
||||
MySerial.begin(38400); /* Trick: use a "high" data rate (less time wasted in ISR and for transmitting each character) */
|
||||
|
||||
VirtualPortNb = TinyPinChange_RegisterIsr(FIRST_INPUT, InterruptFunctionToCall);
|
||||
VirtualPortNb_ = TinyPinChange_RegisterIsr(SECOND_INPUT, InterruptFunctionToCall);
|
||||
|
||||
/* Enable Pin Change for each pin */
|
||||
TinyPinChange_EnablePin(FIRST_INPUT);
|
||||
TinyPinChange_EnablePin(SECOND_INPUT);
|
||||
|
||||
MySerial.txMode();
|
||||
MySerial.println(F("\n*** Tiny PinChange Demo (Rising AND Falling edges) ***"));
|
||||
MySerial.print(F("Pin "));MySerial.print((int)FIRST_INPUT);
|
||||
MySerial.print(F(" is part of virtual port "));MySerial.println((int)VirtualPortNb);
|
||||
|
||||
MySerial.print(F("Pin "));MySerial.print((int)SECOND_INPUT);
|
||||
MySerial.print(F(" is part of virtual port "));MySerial.println((int)VirtualPortNb_);
|
||||
|
||||
MySerial.println(F("As you can see, virtual port is always port 0 for ATtiny85"));
|
||||
MySerial.println(F("Remember <TinyPinChange> is also designed for UNO, MEGA, ATtiny84 and ATtiny167 ;-)"));
|
||||
MySerial.println(F("Type 1 to start display, 0 to stop display"));
|
||||
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
MySerial.rxMode(); /* Switch to Rx Mode */
|
||||
}
|
||||
|
||||
/* Function called in interruption in case of change on pins */
|
||||
void InterruptFunctionToCall(void)
|
||||
{
|
||||
if(TinyPinChange_Edge(VirtualPortNb, FIRST_INPUT)) /* Check FIRST_INPUT has changed (falling or rising edge) */
|
||||
{
|
||||
FirstInputChangeCount++; /* Rising AND Falling edges are counted */
|
||||
}
|
||||
|
||||
if(TinyPinChange_Edge(VirtualPortNb_, SECOND_INPUT)) /* Check SECOND_INPUT has changed (falling or rising edge) */
|
||||
{
|
||||
SecondInputChangeCount++; /* Rising AND Falling edges are counted */
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static boolean State = HIGH, DisplayEnabled = true;
|
||||
static uint32_t LedStartMs = millis(), DisplayStartMs = millis();
|
||||
uint16_t LocalFirstInputChangeCount;
|
||||
uint16_t LocalSecondInputChangeCount;
|
||||
|
||||
/* Blink the built-in LED */
|
||||
if(millis() - LedStartMs >= 500)
|
||||
{
|
||||
LedStartMs = millis();
|
||||
digitalWrite(LED_PIN, State);
|
||||
State = !State; /* State will be inverted at the next digitalWrite() */
|
||||
}
|
||||
|
||||
/* Get command from single wire SoftSerial */
|
||||
if(MySerial.available())
|
||||
{
|
||||
switch(MySerial.read())
|
||||
{
|
||||
case '0':
|
||||
DisplayEnabled = false;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
DisplayEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Diplay Transition numbers every second */
|
||||
if((millis() - DisplayStartMs >= 1000) && DisplayEnabled)
|
||||
{
|
||||
DisplayStartMs = millis();
|
||||
noInterrupts(); /* Mandatory since counters are 16 bits */
|
||||
LocalFirstInputChangeCount = FirstInputChangeCount;
|
||||
LocalSecondInputChangeCount = SecondInputChangeCount;
|
||||
interrupts();
|
||||
MySerial.txMode();
|
||||
MySerial.print(F("FirstInputChangeCount="));MySerial.println(LocalFirstInputChangeCount);
|
||||
MySerial.print(F("SecondInputChangeCount="));MySerial.println(LocalSecondInputChangeCount);
|
||||
MySerial.rxMode();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2013/2014
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
*******************************************************
|
||||
* <TinyPinChange> library Demo *
|
||||
* with debugging capabilities using *
|
||||
* <SoftSerial> object as single wire serial interface *
|
||||
*******************************************************
|
||||
|
||||
This sketch demonstrates how to use <TinyPinChange> library.
|
||||
It counts all the FALLING edges on 2 different pins.
|
||||
/!\CAUTION/!\: as <TinyPinChange> library can be shared (and it is with SoftSerial in this sketch) , the user shall test if the changes are related to the declared pins.
|
||||
|
||||
Trick: By connecting Pin#1 to Pin#0 or to Pin#5 through a 1K resistor, you can generate transitions for testing purpose.
|
||||
Output results are sent to a software serial.
|
||||
|
||||
And the great thing is: using a <SoftSerial> object as a bi-directionnal software serial port (half-duplex) on a single pin to communicate with the outside world!
|
||||
|
||||
To display the sketch results on a PC (in a Terminal):
|
||||
1) Build the "Serial One Wire Debug Cable" and plug it to the regular RS232 port as depicted below,
|
||||
2) Open your favorite Terminal at 38400,n,8,1: HyperTerminal, Teraterm (Windows) or Minicom, GtkTerm (Linux) and CoolTerm (MAC) does the trick.
|
||||
3) You can also use the Serial Monitor of the arduino IDE: Tools->Serial Port and select your RS232 port (may be an USB virtual port), Rate=38400.
|
||||
4) To enable the display, type 1, to disable, type 0 in the Terminal/Monitor.
|
||||
|
||||
SERIAL ONE WIRE
|
||||
DEBUGGING CABLE
|
||||
_______________ ________________
|
||||
/ \___/\___/ \
|
||||
____
|
||||
.--------. | \
|
||||
| GND |--------------------------------+---o5 \
|
||||
| | 47K | | 9o |
|
||||
| | .--###--' | o4 |
|
||||
| DEBUG | 4.7K | | 8o |
|
||||
| TX_RX |-------------------###--+--|<|------o3 | ---> To regular RS232 SubD 9 pins Male of PC or Serial/USB adapter
|
||||
| PIN | ^ | 1N4148 | 7o |
|
||||
| | | '-----------o2 |
|
||||
'--------' | | 6o |
|
||||
ATtiny85 Single | o1 /
|
||||
(Digispark) I/O |____/
|
||||
SubD 9 pins
|
||||
Female
|
||||
*/
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftSerial.h>
|
||||
|
||||
#define LED_PIN 1
|
||||
|
||||
#define DEBUG_TX_RX_PIN 2
|
||||
|
||||
#define FIRST_INPUT 0
|
||||
#define SECOND_INPUT 5
|
||||
|
||||
volatile uint16_t FirstInputChangeCount = 0; /* Volatile since the variable will be updated in interruption */
|
||||
volatile uint16_t SecondInputChangeCount = 0; /* Volatile since the variable will be updated in interruption */
|
||||
|
||||
SoftSerial MySerial(DEBUG_TX_RX_PIN, DEBUG_TX_RX_PIN, true); /* Tx/Rx on a single Pin !!! (Pin#2) */
|
||||
|
||||
uint8_t VirtualPortNb;
|
||||
uint8_t VirtualPortNb_;
|
||||
|
||||
void setup()
|
||||
{
|
||||
TinyPinChange_Init();
|
||||
|
||||
MySerial.begin(38400); /* Trick: use a "high" data rate (less time wasted in ISR and for transmitting each character) */
|
||||
|
||||
VirtualPortNb = TinyPinChange_RegisterIsr(FIRST_INPUT, InterruptFunctionToCall);
|
||||
VirtualPortNb_ = TinyPinChange_RegisterIsr(SECOND_INPUT, InterruptFunctionToCall);
|
||||
|
||||
/* Enable Pin Change for each pin */
|
||||
TinyPinChange_EnablePin(FIRST_INPUT);
|
||||
TinyPinChange_EnablePin(SECOND_INPUT);
|
||||
|
||||
MySerial.txMode();
|
||||
MySerial.println(F("\n*** Tiny PinChange Demo (Falling Edge) ***"));
|
||||
MySerial.print(F("Pin "));MySerial.print((int)FIRST_INPUT);
|
||||
MySerial.print(F(" is part of virtual port "));MySerial.println((int)VirtualPortNb);
|
||||
|
||||
MySerial.print(F("Pin "));MySerial.print((int)SECOND_INPUT);
|
||||
MySerial.print(F(" is part of virtual port "));MySerial.println((int)VirtualPortNb_);
|
||||
|
||||
MySerial.println(F("As you can see, virtual port is always port 0 for ATtiny85"));
|
||||
MySerial.println(F("Remember <TinyPinChange> is also designed for UNO, MEGA, ATtiny84 and ATtiny167 ;-)"));
|
||||
MySerial.println(F("Type 1 to start display, 0 to stop display"));
|
||||
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
MySerial.rxMode(); /* Switch to Rx Mode */
|
||||
}
|
||||
|
||||
/* Function called in interruption in case of change on pins */
|
||||
void InterruptFunctionToCall(void)
|
||||
{
|
||||
if(TinyPinChange_FallingEdge(VirtualPortNb, FIRST_INPUT)) /* Check for FIRST_INPUT Rising Edge */
|
||||
{
|
||||
FirstInputChangeCount++; /* Only Falling edges are counted */
|
||||
}
|
||||
|
||||
if(TinyPinChange_FallingEdge(VirtualPortNb_, SECOND_INPUT)) /* Check for SECOND_INPUT Rising Edge */
|
||||
{
|
||||
SecondInputChangeCount++; /* Only Falling edges are counted */
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static boolean State = HIGH, DisplayEnabled = true;
|
||||
static uint32_t LedStartMs = millis(), DisplayStartMs = millis();
|
||||
uint16_t LocalFirstInputChangeCount;
|
||||
uint16_t LocalSecondInputChangeCount;
|
||||
|
||||
/* Blink the built-in LED */
|
||||
if(millis() - LedStartMs >= 500)
|
||||
{
|
||||
LedStartMs = millis();
|
||||
digitalWrite(LED_PIN, State);
|
||||
State = !State; /* State will be inverted at the next digitalWrite() */
|
||||
}
|
||||
|
||||
/* Get command from single wire SoftSerial */
|
||||
if(MySerial.available())
|
||||
{
|
||||
switch(MySerial.read())
|
||||
{
|
||||
case '0':
|
||||
DisplayEnabled = false;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
DisplayEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Diplay Transition numbers every second */
|
||||
if((millis() - DisplayStartMs >= 1000) && DisplayEnabled)
|
||||
{
|
||||
DisplayStartMs = millis();
|
||||
noInterrupts(); /* Mandatory since counters are 16 bits */
|
||||
LocalFirstInputChangeCount = FirstInputChangeCount;
|
||||
LocalSecondInputChangeCount = SecondInputChangeCount;
|
||||
interrupts();
|
||||
MySerial.txMode();
|
||||
MySerial.print(F("FirstInputChangeCount="));MySerial.println(LocalFirstInputChangeCount);
|
||||
MySerial.print(F("SecondInputChangeCount="));MySerial.println(LocalSecondInputChangeCount);
|
||||
MySerial.rxMode();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2013/2014
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
*******************************************************
|
||||
* <TinyPinChange> library Demo *
|
||||
* with debugging capabilities using *
|
||||
* <SoftSerial> object as single wire serial interface *
|
||||
*******************************************************
|
||||
|
||||
This sketch demonstrates how to use <TinyPinChange> library.
|
||||
It counts all the RISING edges on 2 different pins.
|
||||
/!\CAUTION/!\: as <TinyPinChange> library can be shared (and it is with SoftSerial in this sketch) , the user shall test if the changes are related to the declared pins.
|
||||
|
||||
Trick: By connecting Pin#1 to Pin#0 or to Pin#5 through a 1K resistor, you can generate transitions for testing purpose.
|
||||
Output results are sent to a software serial.
|
||||
|
||||
And the great thing is: using a <SoftSerial> object as a bi-directionnal software serial port (half-duplex) on a single pin to communicate with the outside world!
|
||||
|
||||
To display the sketch results on a PC (in a Terminal):
|
||||
1) Build the "Serial One Wire Debug Cable" and plug it to the regular RS232 port as depicted below,
|
||||
2) Open your favorite Terminal at 38400,n,8,1: HyperTerminal, Teraterm (Windows) or Minicom, GtkTerm (Linux) and CoolTerm (MAC) does the trick.
|
||||
3) You can also use the Serial Monitor of the arduino IDE: Tools->Serial Port and select your RS232 port (may be an USB virtual port), Rate=38400.
|
||||
4) To enable the display, type 1, to disable, type 0 in the Terminal/Monitor.
|
||||
|
||||
SERIAL ONE WIRE
|
||||
DEBUGGING CABLE
|
||||
_______________ ________________
|
||||
/ \___/\___/ \
|
||||
____
|
||||
.--------. | \
|
||||
| GND |--------------------------------+---o5 \
|
||||
| | 47K | | 9o |
|
||||
| | .--###--' | o4 |
|
||||
| DEBUG | 4.7K | | 8o |
|
||||
| TX_RX |-------------------###--+--|<|------o3 | ---> To regular RS232 SubD 9 pins Male of PC or Serial/USB adapter
|
||||
| PIN | ^ | 1N4148 | 7o |
|
||||
| | | '-----------o2 |
|
||||
'--------' | | 6o |
|
||||
ATtiny85 Single | o1 /
|
||||
(Digispark) I/O |____/
|
||||
SubD 9 pins
|
||||
Female
|
||||
*/
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftSerial.h>
|
||||
|
||||
#define LED_PIN 1
|
||||
|
||||
#define DEBUG_TX_RX_PIN 2
|
||||
|
||||
#define FIRST_INPUT 0
|
||||
#define SECOND_INPUT 5
|
||||
|
||||
volatile uint16_t FirstInputChangeCount = 0; /* Volatile since the variable will be updated in interruption */
|
||||
volatile uint16_t SecondInputChangeCount = 0; /* Volatile since the variable will be updated in interruption */
|
||||
|
||||
SoftSerial MySerial(DEBUG_TX_RX_PIN, DEBUG_TX_RX_PIN, true); /* Tx/Rx on a single Pin !!! (Pin#2) */
|
||||
|
||||
uint8_t VirtualPortNb;
|
||||
uint8_t VirtualPortNb_;
|
||||
|
||||
void setup()
|
||||
{
|
||||
TinyPinChange_Init();
|
||||
|
||||
MySerial.begin(38400); /* Trick: use a "high" data rate (less time wasted in ISR and for transmitting each character) */
|
||||
|
||||
VirtualPortNb = TinyPinChange_RegisterIsr(FIRST_INPUT, InterruptFunctionToCall);
|
||||
VirtualPortNb_ = TinyPinChange_RegisterIsr(SECOND_INPUT, InterruptFunctionToCall);
|
||||
|
||||
/* Enable Pin Change for each pin */
|
||||
TinyPinChange_EnablePin(FIRST_INPUT);
|
||||
TinyPinChange_EnablePin(SECOND_INPUT);
|
||||
|
||||
MySerial.txMode();
|
||||
MySerial.println(F("\n*** Tiny PinChange Demo (Rising Edge) ***"));
|
||||
MySerial.print(F("Pin "));MySerial.print((int)FIRST_INPUT);
|
||||
MySerial.print(F(" is part of virtual port "));MySerial.println((int)VirtualPortNb);
|
||||
|
||||
MySerial.print(F("Pin "));MySerial.print((int)SECOND_INPUT);
|
||||
MySerial.print(F(" is part of virtual port "));MySerial.println((int)VirtualPortNb_);
|
||||
|
||||
MySerial.println(F("As you can see, virtual port is always port 0 for ATtiny85"));
|
||||
MySerial.println(F("Remember <TinyPinChange> is also designed for UNO, MEGA, ATtiny84 and ATtiny167 ;-)"));
|
||||
MySerial.println(F("Type 1 to start display, 0 to stop display"));
|
||||
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
MySerial.rxMode(); /* Switch to Rx Mode */
|
||||
}
|
||||
|
||||
/* Function called in interruption in case of change on pins */
|
||||
void InterruptFunctionToCall(void)
|
||||
{
|
||||
if(TinyPinChange_RisingEdge(VirtualPortNb, FIRST_INPUT)) /* Check for FIRST_INPUT Rising Edge */
|
||||
{
|
||||
FirstInputChangeCount++; /* Only Rising edges are counted */
|
||||
}
|
||||
|
||||
if(TinyPinChange_RisingEdge(VirtualPortNb_, SECOND_INPUT)) /* Check for SECOND_INPUT Rising Edge */
|
||||
{
|
||||
SecondInputChangeCount++; /* Only Rising edges are counted */
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static boolean State = HIGH, DisplayEnabled = true;
|
||||
static uint32_t LedStartMs = millis(), DisplayStartMs = millis();
|
||||
uint16_t LocalFirstInputChangeCount;
|
||||
uint16_t LocalSecondInputChangeCount;
|
||||
|
||||
/* Blink the built-in LED */
|
||||
if(millis() - LedStartMs >= 500)
|
||||
{
|
||||
LedStartMs = millis();
|
||||
digitalWrite(LED_PIN, State);
|
||||
State = !State; /* State will be inverted at the next digitalWrite() */
|
||||
}
|
||||
|
||||
/* Get command from single wire SoftSerial */
|
||||
if(MySerial.available())
|
||||
{
|
||||
switch(MySerial.read())
|
||||
{
|
||||
case '0':
|
||||
DisplayEnabled = false;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
DisplayEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Diplay Transition numbers every second */
|
||||
if((millis() - DisplayStartMs >= 1000) && DisplayEnabled)
|
||||
{
|
||||
DisplayStartMs = millis();
|
||||
noInterrupts(); /* Mandatory since counters are 16 bits */
|
||||
LocalFirstInputChangeCount = FirstInputChangeCount;
|
||||
LocalSecondInputChangeCount = SecondInputChangeCount;
|
||||
interrupts();
|
||||
MySerial.txMode();
|
||||
MySerial.print(F("FirstInputChangeCount="));MySerial.println(LocalFirstInputChangeCount);
|
||||
MySerial.print(F("SecondInputChangeCount="));MySerial.println(LocalSecondInputChangeCount);
|
||||
MySerial.rxMode();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map TinyPinChange
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
TinyPinChange KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
TinyPinChange_Init KEYWORD2
|
||||
TinyPinChange_RegisterIsr KEYWORD2
|
||||
TinyPinChange_EnregistreFonctionInterruption KEYWORD2
|
||||
TinyPinChange_EnablePin KEYWORD2
|
||||
TinyPinChange_ActiveBroche KEYWORD2
|
||||
TinyPinChange_DisablePin KEYWORD2
|
||||
TinyPinChange_DesactiveBroche KEYWORD2
|
||||
TinyPinChange_GetPortEvent KEYWORD2
|
||||
TinyPinChange_RetourneEvenemenPort KEYWORD2
|
||||
TinyPinChange_GetCurPortSt KEYWORD2
|
||||
TinyPinChange_RetourneEtatCourantPort KEYWORD2
|
||||
TinyPinChange_PinToMsk KEYWORD2
|
||||
TinyPinChange_MasqueDeBroche KEYWORD2
|
||||
TinyPinChange_Edge KEYWORD2
|
||||
TinyPinChange_Front KEYWORD2
|
||||
TinyPinChange_RisingEdge KEYWORD2
|
||||
TinyPinChange_FrontMontant KEYWORD2
|
||||
TinyPinChange_FallingEdge KEYWORD2
|
||||
TinyPinChange_FrontDescendant KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
Reference in New Issue
Block a user