Could I please ask for some assistance in debugging my "V-tail Blender" sketch. This is intended to reconstruct the rudder signal from the two V-tail channels, to help a friend out who does not have enough receiver channels to control his nose wheel steering servo.
The basis is Phil G's Digispark V-tail mixer. It is mostly the same code (although I changed some of the variable names), but it only has one output channel, and of course the adapted arithmetic.
I use a FlySky receiver, channels 2 and 4. I tap the through-going servo wires to the V-tail servo's, and connect those to P0 and P4. The Digispark calculates the rudder channel, and puts this out on P2.
The bug: P0 seems to block the Rx channel and locks it high. I checked this with the pulse meter and with an ordinary multimeter. There is no short circuit between either GND or Vcc. P0 is declared as input. There is no movement on the connected servo.
P4 is fine, I can read a pulse there and the connected servo functions properly.
Swapping the Rx channels at the receiver does not change anything, P0 remains "cold".
I cannot find fault in the sketch. I did reprogram the Digispark with usbasp several times and it completes the upload as usual. As P0 is also the MOSI connection, can I conclude that the processor is ok?
This is my code:
Code: Select all
/*
* V-Tail channel blender to reconstruct the rudder channel, to control the nose wheel steering.
* Based on the 50:50 Vtail mixer for ATTiny85 such as the 16mhz DigiSpark board by Phil_G.
* By Max Zuijdendorp, september 2021.
*/
#define Rxch1 0 // receiver channel connected to P0
#define Rxch2 4 // receiver channel connected to P4
#define servoOut 2
volatile unsigned long timer_ch1, timer_ch2; // all timer variables are unsigned long
volatile int pulse_time1 = 1500, pulse_time2 = 1500, inpulse_time1 = 1500, inpulse_time2 = 1500, servoPulse = 1500;
volatile byte ch1Was = 0, ch2Was = 0, sync = 0;
void setup()
{
pinMode(servoOut, OUTPUT);
pinMode(Rxch1, INPUT);
pinMode(Rxch2, INPUT);
timer_ch1 = 0; timer_ch2 = 0;
GIMSK = (1 << PCIE); // Enable Pin Change Interrupts
PCMSK = (1 << Rxch1) | (1 << Rxch2); // 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();
inpulse_time1 = pulse_time1; // do an atomic copy in the quickest way
inpulse_time2 = pulse_time2;
sei();
inpulse_time1 /= 2; // then do arithmetic on the copies...
inpulse_time2 /= 2;
servoPulse = inpulse_time1 + inpulse_time2;
// servoPulse = 3000 - servoPulse; // reverse servo rotation
constrain(servoPulse, 850, 2150);
digitalWrite(servoOut, 1); delayMicroseconds(servoPulse); digitalWrite(servoOut, 0); // servo out
}
ISR(PCINT0_vect)
{
if (PINB & (1<<Rxch1)) {
if (ch1Was == 0) {
timer_ch1 = micros();
ch1Was = 1;
}
} else {
if (ch1Was == 1) {
pulse_time1 = ((volatile int)micros() - timer_ch1);
ch1Was = 0;
sync = 1;
}
}
if (PINB & (1<<Rxch2)) {
if (ch2Was == 0) {
timer_ch2 = micros();
ch2Was = 1;
}
} else {
if (ch2Was == 1) {
pulse_time2 = ((volatile int)micros() - timer_ch2);
ch2Was = 0;
}
}
}
Cheers,
Max.