I'm trying to read the forward/reverse signal from a 2in1 receiver/ESC of an RC car (MN82) that is being sent to a motor driver similar to the TA6586 (except PIN 1 and 2 are reversed)
Datasheet TA6586 (english) https://www.micros.com.pl/mediaserver/UITA6586_0001.pdf
Actual IC is SA8336 (chinese, can be translated using Google Translate) https://www.sytatek.com/uploads/soft/SA8336-CN-V1.2.pdf
I can't seem to wrap my head around why the PWM signal appears inverted yet the motor driver IC is working as intended, PWM signal seems to be about 543hz?
This is the test code I have so far, I can't seem to figure out how braking works or when it's in low speed mode (max 50% duty cycles + drag brakes)
I'm using an Arduino Nano with the 2 external interrupts, I've switched to measuring the low time and it seems better now as opposed to high time and subtracting the period lenght (even though it starts on a rising edge)
Is it also ok to write to the servo inside the ISR functions?
#include <Servo.h>
#include <digitalWriteFast.h>
#define PIN_FWD 2
#define PIN_REV 3
#define ESC_PIN 5
/*#define ESC_MIN 1000
#define ESC_CENTER 1500
#define ESC_MAX 2000*/
#define ESC_MIN 0
#define ESC_CENTER 90
#define ESC_MAX 180
#define pulsePeriodMin 60
#define pulsePeriodMax 1936
volatile unsigned long startTimeFwd = 0;
volatile unsigned long currTimeFwd = 0;
volatile int pulseWidthFwd = 0;
volatile unsigned long startTimeRev = 0;
volatile unsigned long currTimeRev = 0;
volatile int pulseWidthRev = 0;
int pulseWidthDuty = 0;
int forwardPinState = 0;
int reversePinState = 0;
Servo ESC;
void setup() {
Serial.begin(9600);
pinModeFast(PIN_FWD, INPUT);
pinModeFast(PIN_REV, INPUT);
attachInterrupt(digitalPinToInterrupt(PIN_FWD), PulseTimerFwd, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_REV), PulseTimerRev, CHANGE);
ESC.attach(ESC_PIN);
ESC.write(ESC_CENTER);
// TODO: Setup code for arming ESC
}
void loop() {
forwardPinState = digitalReadFast(PIN_FWD);
reversePinState = digitalReadFast(PIN_REV);
// Signal is inverted?
if (forwardPinState == LOW && reversePinState == HIGH)
{
// Forward
pulseWidthDuty = map(pulseWidthFwd, pulsePeriodMin, pulsePeriodMax, 0, 100);
Serial.println("Forward PW " + String(pulseWidthFwd) + "ms, duty " + String(pulseWidthDuty) + "%");
}
else if (forwardPinState == HIGH && reversePinState == LOW)
{
// Reverse
pulseWidthDuty = map(pulseWidthRev, pulsePeriodMin, pulsePeriodMax, 0, 100);
Serial.println("Reverse PW " + String(pulseWidthRev) + "ms, duty " + String(pulseWidthDuty) + "%");
}
/*else if (forwardPinState == HIGH && reversePinState == HIGH)
{
// This never occurs?
Serial.println("Brake");
}*/
else if (forwardPinState == LOW && reversePinState == LOW)
{
// Idle
ESC.write(ESC_CENTER);
}
delay(20);
}
void PulseTimerFwd() {
// FALLING
if (digitalReadFast(PIN_FWD) == LOW)
{
startTimeFwd = micros();
}
else
{
// RISING
pulseWidthFwd = micros() - startTimeFwd;
ESC.write(map(pulseWidthFwd, pulsePeriodMin, pulsePeriodMax, ESC_CENTER, ESC_MAX));
}
}
void PulseTimerRev() {
// FALLING
if (digitalReadFast(PIN_REV) == LOW)
{
startTimeRev = micros();
}
else
{
// RISING
pulseWidthRev = micros() - startTimeRev;
ESC.write(map(pulseWidthRev, pulsePeriodMin, pulsePeriodMax, ESC_CENTER, ESC_MIN));
}
}