Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save mcmatrix/69945a430f6e47e55e4a401aa265ff1c to your computer and use it in GitHub Desktop.

Select an option

Save mcmatrix/69945a430f6e47e55e4a401aa265ff1c to your computer and use it in GitHub Desktop.
/*
* 2017 <Janar Sööt> http://opensource.org/licenses/mit-license.php
* Based on the work from @jhsa (http://openrcforums.com/forum/viewtopic.php?f=85&t=8471)
*
* I do not take any responsibility for this program. Use at your own risk.
___ ___
D5(A0) RESET PCINT5 B5 -| o |- VCC
D3(A3) ADC3 PCINT3 B3 -|atiny|- B2 PCINT2 SCK ADC1 D2(A1)
D4(A2) ADC2 PCINT4 B4 -|45/85|- B1 PCINT1 MISO D1
GND -|_/25_|- B0 PCINT0 MOSI D0
*/
// Connections:
// VCC/GND,
// B0, to mosfet controlling EXT module power
// B1, to mosfet controlling INT module power
// B3, to PPM output INT module (PPM2)
// B4, to PPM output EXT module (PPM1)
// B2, to LED (optional)
extern "C" {
#include <util/atomic.h>
}
// Comment out if not using a LED (internal module)
#define USE_LED
const int ledPin = 2; // optional LED
// Comment out if not using a internal module
#define USE_INT_MODULE
const int inputPin_INT = 3; // Connect to PPM output internal Module (PPM2)
const int outputPin_INT = 1; // Output Internal Module
// Comment out if not using a external module
#define USE_EXT_MODULE
const int inputPin_EXT = 4; // Connect to PPM output external Module (PPM1)
const int outputPin_EXT = 0; // Output external Module
unsigned long previousMillis_INT = 0; // will store last time the output was updated
unsigned long previousMillis_EXT = 0;
const long interval_INT = 2000; // interval (milliseconds) to leave output HIGH (ON delay)
const long interval_EXT = 2000;
byte intPin_bm = 0, extPin_bm = 0;
volatile byte portPreviousState = 0;
volatile byte changedPortBits = 0;
void setup() {
#ifdef USE_LED
pinMode(ledPin, OUTPUT); // pin controlling LED
#endif /* USE_LED */
#ifdef USE_INT_MODULE
pinMode(inputPin_INT, INPUT); // pin listening module PPM signal or switch
pinMode(outputPin_INT, OUTPUT); // pin controlling mosfet (module power)
intPin_bm = digitalPinToBitMask(inputPin_INT); // map Arduino pin to actual AVR port bitmask
*digitalPinToPCMSK(inputPin_INT) |= (1 << digitalPinToPCMSKbit(inputPin_INT)); // use pin as interrupt source
*digitalPinToPCICR(inputPin_INT) |= (1 << digitalPinToPCICRbit(inputPin_INT)); // enable pin change interrupts, more like port change interrupt :)
#endif /* USE_INT_MODULE */
#ifdef USE_EXT_MODULE
pinMode(inputPin_EXT, INPUT); // pin listening module PPM signal or switch
pinMode(outputPin_EXT, OUTPUT); // pin controlling mosfet (module power)
extPin_bm = digitalPinToBitMask(inputPin_EXT); // map Arduino pin to actual AVR port bitmask
*digitalPinToPCMSK(inputPin_EXT) |= (1 << digitalPinToPCMSKbit(inputPin_EXT)); // Use pin as interrupt source
*digitalPinToPCICR(inputPin_EXT) |= (1 << digitalPinToPCICRbit(inputPin_EXT)); // enable pin change interrupts, more like port change interrupt :)
#endif /* USE_EXT_MODULE */
// save port B state for comparison
portPreviousState = PINB;
// enable interrupts
interrupts();
}
void loop() {
unsigned long currentMillis = millis();
#ifdef USE_INT_MODULE
if(changedPortBits & intPin_bm) { // INT PPM changed
// read and clear atomic begin (IMPORTANT)
ATOMIC_BLOCK(ATOMIC_FORCEON) {
// clear changed bit.
changedPortBits &= ~intPin_bm;
}
digitalWrite(outputPin_INT, HIGH);
#ifdef USE_LED
digitalWrite(ledPin, HIGH); // turn led on
#endif /* USE_LED */
// reset timer
previousMillis_INT = currentMillis;
} else if (currentMillis - previousMillis_INT >= interval_INT) {
// interval has elapsed without any change in ppm signal so turn it off
digitalWrite(outputPin_INT, LOW);
#ifdef USE_LED
digitalWrite(ledPin, LOW); // turn led off
#endif /* USE_LED */
}
#endif /* USE_INT_MODULE */
#ifdef USE_EXT_MODULE
if(changedPortBits & extPin_bm) { // EXT PPM changed
// read and clear atomic begin (IMPORTANT)
ATOMIC_BLOCK(ATOMIC_FORCEON) {
// clear changed bit.
changedPortBits &= ~extPin_bm;
}
digitalWrite(outputPin_EXT, HIGH);
// reset timer
previousMillis_EXT = currentMillis;
} else if (currentMillis - previousMillis_EXT >= interval_EXT) {
// interval has elapsed without any change in ppm signal so turn it off
digitalWrite(outputPin_EXT, LOW);
}
#endif /* USE_EXT_MODULE */
}
ISR(PCINT0_vect) {
byte portState = PINB;
// calc changed port bits
changedPortBits = portState ^ portPreviousState;
// save the new state for next comparison
portPreviousState = portState;
}
@mcmatrix
Copy link
Copy Markdown
Author

mcmatrix commented May 16, 2017

I'm using damellis attiny core for Arduino IDE (https://github.com/damellis/attiny)
Follow the installation guide from http://highlowtech.org/?p=1695

http://openrcforums.com/forum/viewtopic.php?f=85&t=8471
The fuses are:
Low - E2
High - DF
Extended - FF
On the Arduino IDE, you should select "Attiny85, 8Mhz internal clock" as the board..

avrdude.exe -c stk500v2 -p attiny85 -P usb -B 5 -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m -v

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment