De pulswijdte zal 1500 zijn, naar dat kan ik nog even kontroleren.
Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature may not be available in some browsers.
Volgens mij herkent de ATtiny geen "pulseIn". Ik heb voor de converter naar een soort GG (Webra Picco) in Gerard's Topsy de volgende schets geschreven, gebaseerd op Phil_G's sketch. In dit geval ging het om een magnetische actuator die heen en weer beweegt afhankelijk van de Mark/Space ratio, maar dat zou je moeten aanpassen naar de behoefte van een echte GG.Lijkt een goed idee, maar deze sketch geeft bij mij een compileerfout bij de AtTiny 85, maar niet bij een Nano/ProMini....![]()
// Simple recoder for ATTiny85 board and MIC4427 non-inverting MOSFET driver - Max Z
// Based on sketch digispark_gg_v2 by Phil G, revised for Webra Picco actuator (relay type)
// Fixed DrvCycle time, not controlled by elevator pulse ( as would be required for full GG)
// Mark-space between 30%-70% controlled by rudder channel
#define rudder_ch 2 // receiver rudder channel connected to P2 (ATTiny physical pin 7)
#define speedpot A3
#define PiccoDriver 1 // output to driver chip
#define RUDD_DFLT 1500 // neutral rudder on power-up
volatile unsigned long timer_ch1_R; // all timer variables are unsigned long (volatile because ISR variable)
volatile int pulse_time_R = RUDD_DFLT; // (volatile because ISR variable)
volatile byte ch1Rwas = 0; // previous hi/lo state (volatile because ISR variable)
int rudder_time = RUDD_DFLT; // measured channel pulses from rx
int speedread; // analog read from pot
unsigned long rudder_marksp = 0, settle_time;
unsigned long DrvOn = 0, DrvOff = 0, DrvCycle = 140; // driver on/off/cycle times in ms
void setup() {
pinMode(rudder_ch, INPUT_PULLUP); // pullups in case rx isnt connected, avoids picking up hash
pinMode(PiccoDriver, OUTPUT); // o/p to PiccoDriver
pinMode(speedpot, INPUT_PULLUP);
timer_ch1_R = 0;
GIMSK = (1 << PCIE); // Enable Pin Change Interrupts
PCMSK = (1 << rudder_ch); // Enable interrupts for rx channel input
sei();
settle_time = micros() + 500000; // 500 milliseconds to allow rx outputs to settle on power-up
}
void loop() {
if (micros() < settle_time) { pulse_time_R = RUDD_DFLT; }
cli();
rudder_time = pulse_time_R; // do an atomic copy in the quickest way
sei();
speedread = analogRead(speedpot);
DrvCycle = map (speedread,0,1023,300,80);
rudder_time = constrain(rudder_time, 1000, 2000);
rudder_marksp = map(rudder_time, 1050, 1950, 10, 90); // map to 10% - 90%
DrvOn = DrvCycle * rudder_marksp / 100;
DrvOff = DrvCycle - DrvOn;
if (rudder_time > 1950) {
digitalWrite(PiccoDriver, HIGH);
}
else if (rudder_time < 1050) {
digitalWrite(PiccoDriver, LOW);
}
else {
// waggle the driver on and off
digitalWrite(PiccoDriver, HIGH); delay(DrvOn); digitalWrite(PiccoDriver, LOW); delay(DrvOff);
}
}
ISR(PCINT0_vect) // read the receiver channels into timer_ch1_R
{
if (PINB & (1 << rudder_ch)) { // Rx ch 1
if (ch1Rwas == 0) {
timer_ch1_R = micros();
ch1Rwas = 1;
}
} else {
if (ch1Rwas == 1) {
pulse_time_R = ((volatile int)micros() - timer_ch1_R);
ch1Rwas = 0;
}
}
}
Onwaarschijnlijk. Interrupts zijn heel snel, en de uiteindelijke servo-puls word met een simpele delay van maximaal 2 millisecondes gegenereerd direct ná de interrupt. En de volgende Rx-puls komt pas na ongeveer 20 millisecondes.Ik hoop dat het met interrupts niet de uigang gaat verstoren.
//PWM input for ATTiny - based on Phil Green's Digispark V-tail mixer.
#define Rxch1 0 // receiver channel connected to P0 (ATTiny physical pin 5) Set PCMSK to match
#define servo1 4 // servo 1 (ATTiny physical pin 3)
#define led 1 // DigiSpark internal LED on P1 (ATTiny physical pin 6)
#define unused2 2 // define unused/open pins as output to avoid spurious input
#define unused3 3. // define unused/open pins as output to avoid spurious input
volatile unsigned long timer_ch1; // all timer variables are unsigned long
volatile int pulse_time1 = 1500, RXpulse_time1, outpulse_time1 = 1500;
volatile byte ch1Was = 0, sync = 0;
void setup()
{
pinMode(led, OUTPUT);
pinMode(servo1, OUTPUT);
pinMode (unused2, OUTPUT);
pinMode (unused3, OUTPUT);
pinMode(Rxch1, INPUT);
timer_ch1 = 0;
GIMSK = (1 << PCIE); // Enable Pin Change Interrupts
PCMSK = (1 << Rxch1); // Enable interrupts for rx channel inputs
sei();
}
void loop()
{
while (sync == 0);
sync = 0;
delay(6); // do the o/p pulses mid-frame, reduces jitter...
cli();
RXpulse_time1 = pulse_time1; // do an atomic copy in the quickest way
sei();
/* do the math here, output pulse = outpulse_time1
*/
digitalWrite(servo1, 1); delayMicroseconds(outpulse_time1); digitalWrite(servo1, 0); // servo out
}
ISR(PCINT0_vect)
{
if (PINB & 0b00000001) { // read the Rx pulse on P0
if (ch1Was == 0) {
timer_ch1 = micros();
ch1Was = 1;
}
} else {
if (ch1Was == 1) {
pulse_time1 = ((volatile int)micros() - timer_ch1);
ch1Was = 0;
sync = 1;
}
}
}
Dat weet ik ook niet, maar de oscillator is sowieso minder nauwkeurig dan de Arduino's met een kristalgestuurde oscillator.Geen idee wat een hogere spanning bijvoorbeeld voor invloed op de klok kan hebben.
Nee, dat is duidelijk. De structuur van de AtTiny is eenvoudiger dan die van de AtMega 328 processor.Volgens mij herkent de ATtiny geen "pulseIn".
Zoals je ziet wordt de detectie van de Rx pulsen met een ISR interrupt gedaan.
// Switch Slow, adapted from Phil's V-tail mixer for ATTiny85, such as the 16mhz DigiSpark board - Phil_G/ Bruno_vH
#define IN 0 // receiver channel connected to P0 (ATTiny physical pin 5)
#define FS 0
#define OUT 4 // servo connected to P4 (ATTiny physical pin 3)
volatile unsigned long timer, flsv = 1000; // variables are unsigned long
volatile int pulse_time = 1000, outpulse_time = 1000, temp = 0;
volatile byte Was = 0, sync = 0, UP = 0, DWN = 1;
void setup()
{
pinMode(IN, INPUT);
pinMode(FS, INPUT);
pinMode(OUT, OUTPUT);
timer = 0;
GIMSK = (1 << PCIE); // Enable Pin Change Interrupts
PCMSK = (1 << IN); // Enable interrupts for input
sei();
}
void loop()
{
while (sync == 0);
sync = 0;
delay(6); // do the o/p pulses mid-frame, reduces jitter...
cli();
temp = pulse_time; // do an atomic copy in the quickest way
if (temp > 1700) {
outpulse_time = outpulse_time+15; // slowly increase servoposition
}
if (temp < 1300) {
outpulse_time = outpulse_time-15; // slowly decrease servoposition
}
if (outpulse_time < 1000) { // constrain within 1000...2000
outpulse_time = 1000;
}
if (outpulse_time > 2000) { // "
outpulse_time = 2000;
}
digitalWrite(OUT, 1); delayMicroseconds(outpulse_time); digitalWrite(OUT, 0); // servo out on P4/ATTiny physical pin 3
sei();
}
ISR(PCINT0_vect)
{
if (PINB & 0b00000001) {
if (Was == 0) {
timer = micros();
flsv = flsv + 600;
Was = 1;
}
} else {
if (Was == 1) {
pulse_time = ((volatile int)micros() - timer);
Was = 0;
sync = 1;
}
}
}