Hello I am new to this forum and hope someone can help me with my project.
I am building an inverted pendulum, for this i am using a Raspberry pi 4 a teensy 4.0 and an odrive.
The mechanical part is working as expected. However I have a serious issue I have not been able to solve in two weeks and is starting to frustrate me:
My overclocked teensy (ca. 1 Ghz) can apparently not handle the pulses coming from two cui amt 102 v encoders which have 2024 ppr each. I would like to utilize Pauls Encoder library since it supports the 4x counting mode and has optimized headers.
https://www.pjrc.com/teensy/td_libs_Encoder.html#optimize
Additionally i would like to "listen" to two end-line switches utilizing the bounce library.
The data-flow is as follows:
The teensy counts the pulses from cui amt encoders and sends the values to the raspberry pi with usb serial. The raspberry pi decodes the serial packages from the teensy and published them on a redis server that i can access through a python script and visualize the pendulum.
The only remaining problem is that when both encoders are moved quick enough at least one of them is loosing pulses. I think it is because altough the teensy is very fast it is not enough for handling the combined pulses of two encoders.
I suspect that the serial communication is slowing down the pulse reading.
Another plausible idea is that the Encoders that are connected to the teensy draw too much power from the board when turned really fast. (both encoders (5v)and both switches(3v) are fed by the teensy.
I would be really thankfull if anyone can give me some advice on how to solve my issue. I am open to add one or two teensies to my setup. however i would like to keep the usb serial communication with the raspberry pi for gathering all the sensor data, since it is very convenient.
My arduino Sketch is as follows:
#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Bounce.h>
#include <Encoder.h>
#include <iostream>
Encoder angleEncoder(5, 6);
Encoder posEncoder(7, 8);
const int touchSensor_Pin_left = 15;
Bounce touchSensor_left = Bounce(touchSensor_Pin_left, 5);
const int touchSensor_Pin_right = 14;
Bounce touchSensor_right = Bounce(touchSensor_Pin_right, 5);
long anglePulses = 0;
long posPulses=0;
long newanglePulses = 0;
long newposPulses = 0;
String sdata="";
void setup() {
Serial.begin(115200);
anglePulses = 0;
posPulses = 0;
pinMode(touchSensor_Pin_left, INPUT);
pinMode(touchSensor_Pin_right, INPUT);
}
void resetEncoders()
{
anglePulses = 0;
posPulses = 0;
newanglePulses = 0;
newposPulses = 0;
angleEncoder.write(0);
posEncoder.write(0);
}
void resetAngle()
{
//Serial.print("resetting angle");
anglePulses = 0;
newanglePulses = 0;
angleEncoder.write(0);
}
void resetPosition()
{
//Serial.print("resetting position");
posPulses = 0;
newposPulses = 0;
posEncoder.write(0);
}
void writePosition(int decision)
{
int desired_left = -25585;
int desired_right = +25585;
switch(decision)
{ case 1:{
posPulses = desired_left;
newposPulses = desired_left;
posEncoder.write(desired_left);
break;
}
case 2:{
posPulses = desired_right;
newposPulses = desired_right;
posEncoder.write(desired_right);
break;
}
}
}
bool old_left_flag = false;
bool left_flag = false;
bool left_flank = false;
bool old_right_flag = false;
bool right_flag = false;
bool right_flank = false;
char newangle ;
char newpos ;
char left_flag_c ;
char right_flag_c ;
void loop() {
if (touchSensor_left.update())
{
if ((touchSensor_left.risingEdge())&&(!left_flank)) {
left_flag = true;
left_flank =true;
}
if((left_flank)&&(touchSensor_left.fallingEdge())){
left_flank = false;
left_flag = false;
}
}
if (touchSensor_right.update())
{
if ((touchSensor_right.risingEdge())&&(!right_flank)) {
right_flag = true;
right_flank =true;
}
if((right_flank)&&(touchSensor_right.fallingEdge())){
right_flank = false;
right_flag = false;
}
}
newanglePulses = angleEncoder.read();
newposPulses = posEncoder.read();
if ((newanglePulses != anglePulses) || (newposPulses != posPulses) || (right_flag != old_right_flag||left_flag != old_left_flag)) {
Serial.print(newanglePulses);
Serial.print(",");
Serial.print(newposPulses);
Serial.print(",");
Serial.print(left_flag);
Serial.print(",");
Serial.print(right_flag);
Serial.print("\n");
anglePulses = newanglePulses;
posPulses = newposPulses;
old_left_flag = left_flag;
old_right_flag = right_flag;
}
byte ch;
String valStr;
if (Serial.available()) {
ch = Serial.read();
sdata += (char)ch;
if (ch=='\n') { // Command received and ready.
sdata.trim();
switch( sdata.charAt(0) ) {
case 'c':
resetEncoders();
break;
case 'a':
resetAngle();
break;
case 'p':
resetPosition();
break;
case 'r':
writePosition(1);
break;
case 'l':
writePosition(2);
break;
}
sdata = "";
}
}
}