I want to create a python equivalent of the RCPulseIn library for arduino that does all the same functions of the library. I have written up a code that has lots of errors, but has sort of a framework of what I want to do. I have been looking all over for one and even a C++ to python transpiler, however I am unsure of the reliability of them. The C++ code and my code will be posted below. I would appreciate it greatly if someone could clean this up and write an ISR to read the pin's change, which would be the readRC() function in my code. In addition to that, I will need help physically publishing this library so that I can use it and everyone else who wants to can use it. Another thing, I am more or less a newbie to python, however, I have done something similar to this with an arduino, and I know how to do that. Could I use an Arduino as a slave and send the read signals to the Pi so that they could be read that way? Also let me describe what my goal is here: I want to use the raspberry pi 3 Mod. B as a main control module to read signals from a RC receiver like the flysky FS-I6AB to control a servo and two motors to control a model of the USS Nimitz. I am using the pi so that I can have a camera mounted in the superstructure that can stream a live video feed to my phone. I have done something similar using an Arduino, however the arduino is not powerful enough to use the camera, plus I dont have the space to do so. With the Nimitz, I get 3 feet of space to do what I want to do in it. Also, is there a way to use a singular power source to power the pi, and an arduino if the idea of using the arduino as a slave is possible?
import RPi.GPIO as GPIO
import time
import pigpio
GPIO.setmode(GIPO.BCM)
class RCPulsein:
def setupRC(self, pin): #define a GPIO pin as an
input
for a RC receiver
GIPO.setup(pin, GIPO.IN)
if (pin != GIPO.IN):
GIPO.setup(pin, GIPO.IN)
def readRC(pin):
pwm.get_frequency(pin) #read the signal pin's PWM
duty cycle and duration
def deadbandMap(x, in_in, in_de_in, in_de_ax, in_ax,
out_in, out_id, out_ax):
if (in_in > in_ax):
temp = out_ax
out_ax = out_in #maps the value from readRC where
a given center range maps to zero
out_in = temp #and anything above or below
the boundaries to a certain value, for example:
in_ax = in_in #1000 is mapped to -255 and 200
is
mapped to 255 and the interval [1490,1510]
in_in = temp #is mapped to zero. the
variable x
is represented by readRC(pin).
temp = in_de_in
in_de_ax = in_de_in
in_de_in = temp
if (x < in_in):
return out_min
elif (x < in_de_in):
return arduino_map(x, in_in, in_de_in, out_in,
out_id)
elif (x > in_ax):
return out_ax
elif (x > in_de_ax):
return arduino_map(x, in_de_ax, in_ax, out_id,
out_ax)
else:
return out_id
def deadbandMap(x, in_in, in_db, in_ax, out_in, out_ax):
in_double_mid = in_in + in_ax
int(in_dead_min)
int(in_dead_max)
if ((in_in * 2) < in_double_mid):
in_dead_min = (in_double_mid - in_deadband) // 2
#actual keyword used for deadbandMap()
in_dead_max = (in_double_mid + in_deadband) // 2
#in_in is the minimun value that is mapped
else:
in_dead_min = (in_double_mid + in_deadband) // 2
#and in_ax is the maximum. in_db is the center range of
values
in_dead_max = (in_double_mid - in_deadband) //
2 #that are mapped to zero. out_in is the minimun ouput
value,
return deadbandMap(x, in_in, in_de_in, in_de_ax, in_ax,
out_in, out_id, out_ax)#and out_ax is the maximun output
value
def arduino_map(y, in_min, in_max, out_min, out_max):
return (x - i_min) * (o_max - o_min) // (i_max - i_min) + o_min #python definition of the arduino map function
C++ codes
/*
* Efficiently reads the duration of the high voltage in a
pulse train.
* Designed to simplify the use of RC controllers with the
Arduino.
*
* Depends on the EnableInterrupt library.
*
* Author: David Wang, NuVu Studio
*/
#ifndef __RCPULSEIN_H__
#define __RCPULSEIN_H__
#define EI_ARDUINO_INTERRUPTED_PIN
#include <EnableInterrupt.h>
#define PULSESTART(x) pulseStart ##x
#define PULSEDUR(x) pulseDur ##x
#define defineRC(x) \
volatile unsigned long PULSESTART(x); \
volatile unsigned long PULSEDUR(x); \
void interruptFunction ##x () { \
if ( arduinoPinState ) { \
PULSESTART(x)=micros(); \
} else { \
PULSEDUR(x)=micros()-PULSESTART(x); \
} \
}
#define setupRC(x) \
pinMode( x, INPUT_PULLUP); \
enableInterrupt( x, interruptFunction##x, CHANGE)
#define readRC(x) PULSEDUR(x)
/*
* Behaves similarly to the built-in Arduino map function,
but maps a "deadband" section of the input range to middle
value of the output range.
*
* The return value is constrainted to lie within the range
out_min -> out_max.
* The range of x from in_dead_min to in_dead_max is mapped
to the output out_mid.
*/
long deadbandMap(long x, long in_min, long in_dead_min, long
in_dead_max, long in_max, long out_min, long out_mid, long
out_max);
/*
* Behaves similarly to the built-in Arduino map function,
but maps a "deadband" section of the input range to middle
value of the output range.
*
* The return value is constrainted to lie within the range
out_min -> out_max.
* The range of x from in_dead_min to in_dead_max is mapped
to the output out_mid.
*/
long deadbandMap(long x, long in_min, long in_deadband, long
in_max, long out_min, long out_mid, long out_max);
#endif //__RCPULSEIN_H__
and the other:
/*
* Efficiently reads the duration of the high voltage in a
pulse train.
* Designed to simplify the use of RC controllers with the
Arduino.
*
* Depends on the EnableInterrupt library.
*
* Author: David Wang, NuVu Studio
*/
#include <Arduino.h>
/*
* Behaves similarly to the built-in Arduino map function,
but maps a "deadband" section of the input range to middle
value of the output range.
*
* The return value is constrainted to lie within the range
"out_min" to "out_max".
* The range of x from "in_dead_min" to "in_dead_max" is
mapped to the output "out_mid".
* The sequence of arguments "in_min", "in_dead_min",
"in_dead_max", and "in_max" must monotonically increase or
decrease.
* The sequence of arguments "out_min", "out_mid", and
"out_max" must monitonically increase or decrease.
*/
long deadbandMap(long x, long in_min, long in_dead_min, long
in_dead_max, long in_max, long out_min, long out_mid, long
out_max)
{
if(in_min>in_max){
long temp = out_max;
out_max = out_min;
out_min = temp;
temp = in_max;
in_max = in_min;
in_min = temp;
temp = in_dead_max;
in_dead_max = in_dead_min;
in_dead_min = temp;
}
if(x<in_min){
return out_min;
}else if(x<in_dead_min){
return map(x,in_min,in_dead_min,out_min,out_mid);
}else if(x>in_max) {
return out_max;
}else if(x>in_dead_max){
return map (x,in_dead_max,in_max,out_mid,out_max);
}else{
return out_mid;
}
}
/*
* Behaves similarly to the built-in Arduino map function,
but maps a "deadband" section of the input range to middle
value of the output range.
*
* The return value is constrainted to lie within the range
"out_min" to "out_max".
* The range of "deadband" values around the cente rof
"in_min" and "in_max" are mapped to the output "out_mid".
*/
long deadbandMap(long x, long in_min, long in_deadband, long
in_max, long out_min, long out_mid, long out_max)
{
long in_double_mid = in_min+in_max;
long in_dead_min;
long in_dead_max;
if((in_min*2)<in_double_mid){
in_dead_min = (in_double_mid-in_deadband)/2;
in_dead_max = (in_double_mid+in_deadband)/2;
}else{
in_dead_min = (in_double_mid+in_deadband)/2;
in_dead_max = (in_double_mid-in_deadband)/2;
}
return deadbandMap(x,in_min,in_dead_min,in_dead_max,in_max,out_min,out_
mid,out_max);
}
(b) Adafruit PCA9685 16-Channel Servo Driver - Bill Earl 2019 https://cdn-learn.adafruit.com/downloads/pdf/16-channel-pwm-servo-driver.pdf
– tlfong01 Oct 09 '19 at 03:44(2) DIY PWM TO PPM Converter (Arduino) https://oscarliang.com/build-pwm-ppm-converter-arduino-2-4ghz-receiver/.
– tlfong01 Oct 09 '19 at 04:01