Low-pass filter problem

Tabbourg

Member
I'm trying to use two teensy 4.0 microcontrollers to translate serial data to gamepad outputs. I have one teensy taking serial data from one host over USB and sending it to the other teensy using the pins which sends the gamepad output to another host over USB. I set up a simple low-pass filter to try and smooth the PWM voltage, which works ok but, when I send button data I get a small amount of joystick output up and right. Did I connect something wrong? I have them wired like this (The Arduinos represent the Teensys, it was the closest thing in the diagram software). The orange wires are not connected to each other, they connect the same pins on both Teensys. EG: Pin 0 to pin 0, pin 1 to pin 1, etc.:
1733503600958.png


Here is my code.
Left Teensy:

C++:
/* SerialReceive.ino

   Takes serial input and sends it over pins.
*/
const int ledPin = 13;
const int joyXPin = 5;
int xVal = 0;
const int joyYPin = 6;
int yVal = 0;
int buttonIndex = 0, buttonState = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  // Button pins
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  // Joystick pins
  pinMode(joyXPin, OUTPUT);
  pinMode(joyYPin, OUTPUT);
  // Center joystick
  analogWrite(joyXPin, 128);
  analogWrite(joyYPin, 128);
  Serial.begin(38400);
}

int count = 0;
char data[1024];
bool finished = false;

void loop() {
  digitalWrite(ledPin, HIGH);   // set the LED on
  // Read data
  if(Serial.available() > 0 && !finished){
    data[count] = Serial.read();
    if(data[count] == '!'){
      finished = true;
    }

    count++;
  }

  if(finished){
    // Process data
    int index = 1;
    // Joystick data processing
    if(data[0] == 'J'){
      xVal = 0;
      yVal = 0;
      // Get the number of digits for x
      int numDigits = pow(10, data[index++] - 49);
      // Start reading x
      while(data[index] != ','){
        xVal += (data[index] - 48) * numDigits;
        numDigits /= 10;
        index++;
      }
      // Skip comma
      index++;
      // Get the number of digits for y
      numDigits = pow(10, data[index++] - 49);
      // Start reading y
      while(data[index] != '!'){
        yVal += (data[index] - 48) * numDigits;
        numDigits /= 10;
        index++;
      }
    } else if(data[0] == 'B'){
      // Read button
      buttonIndex = data[index++] - 48;
      buttonState = data[index++] - 48;
    }

    if(data[0] == 'J'){
      analogWrite(joyXPin, xVal);
      analogWrite(joyYPin, yVal);
    } else if(data[0] == 'B') {
      digitalWrite(buttonIndex, buttonState);
    }
    
    for(int i = 0; i < count; i++){
      data[i] = '\0';
    }
    count = 0;
    finished = false;
  }

  if(!Serial.available()){
    delay(25);
  }
}

Right Teensy:
C++:
/* GamepadSend.ino

   Takes data from pins and outputs gamepad commands.
*/
#include <cmath>

const int ledPin = 13;
const int deadZoneVal = 35;

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  // Button pins
  pinMode(0, INPUT_PULLDOWN);
  pinMode(1, INPUT_PULLDOWN);
  pinMode(2, INPUT_PULLDOWN);
  pinMode(3, INPUT_PULLDOWN);
  // Joystick pins
  pinMode(A0, INPUT_DISABLE);
  pinMode(A1, INPUT_DISABLE);
}

void loop() {
  int buttonVal = 0;
  // read the digital inputs and set the buttons
  for(int button = 0; button < 4; button++){
    buttonVal = digitalRead(button);
    Joystick.button(button+1, buttonVal);
  }

  // read analog input and set X position
  int xVal = analogRead(A0);
  // Deadzone
  if(abs(xVal - 512) < deadZoneVal){
    xVal = 512;
  }
  Joystick.X(xVal);

  // read analog input and set Y position
  int yVal = analogRead(A1);
  // Deadzone
  if(abs(yVal - 512) < deadZoneVal){
    yVal = 512;
  }
  Joystick.Y(yVal);

  // a brief delay
  delay(25);
}

The capacitors are 50V electrolytic capacitors. https://www.amazon.com/dp/B0CMQC587X?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1
 
I have one teensy taking serial data from one host over USB and sending it to the other teensy using the pins which sends the gamepad output to another host over USB.

Can you please try to explain this in more detail? I don't understand what you're trying to do.
 
Can you please try to explain this in more detail? I don't understand what you're trying to do.
The Teensy running SerialReceive.ino takes serial input over usb from my phone and the Teensy running GamepadSend.ino takes that input and sends gamepad output to my PC. I ultimately want to use my phone as a gamepad with no drivers/software on the host.
 
Is the only connection between the two Teensy's the two PWM outputs from Teensy #1 going to analog inputs on Teensy #2? Is there some reason that needs to be an analog interface? What update rate do you need on that interface?
 
Not shown in that diagram is the connection between the ground pins of the two systems. That is important because one is generating an analog voltage with respect to its ground while the the other is measuring a voltage with respect to its ground.
The two grounds might not be the same.
 
Is the only connection between the two Teensy's the two PWM outputs from Teensy #1 going to analog inputs on Teensy #2? What update rate do you need on that interface?
They are also connected on digital outputs 0-3 from Teensy #1 going to digital inputs 0-3 on Teensy #2. My problem is, both of my analog inputs on Teensy #2 are getting a value of about 600 when any of the digital outputs 0-3 from Teensy #1 are activated.
 
Not shown in that diagram is the connection between the ground pins of the two systems. That is important because one is generating an analog voltage with respect to its ground while the the other is measuring a voltage with respect to its ground.
The two grounds might not be the same.
This sounds like it might be my issue, but I don't know enough electrical engineering to understand what you said or how to apply it. Will connecting the right Teensy's ground to left Teensy's ground fix it?
 
This sounds like it might be my issue, but I don't know enough electrical engineering to understand what you said or how to apply it. Will connecting the right Teensy's ground to left Teensy's ground fix it?
He's saying you also need to connect the two Teensy's GND-to-GND
 
GND is the reference for everything, voltages are always differences between two points.
 
I would also ask for the reason why analog signals are used. Connecting the two microcontroller via one serial interface makes it easy to communicate and send data more reliable. If only one direction is needed, only GND and TX to RX would be necessary.

Not sure if I understand the application. Two Teensy 4.0 seem a bit much for such a simple task. But if two USB connections are necessary maybe that is the easiest way. Maybe somebody else has another idea.
 
I would also ask for the reason why analog signals are used. Connecting the two microcontroller via one serial interface makes it easy to communicate and send data more reliable. If only one direction is needed, only GND and TX to RX would be necessary.

Not sure if I understand the application. Two Teensy 4.0 seem a bit much for such a simple task. But if two USB connections are necessary maybe that is the easiest way. Maybe somebody else has another idea.
The two Teensy are connected to separate hosts that only have usb-a ports. I asked for advice on the basic idea in another thread before starting and got zero replies. If the setup is bad/dumb it is because I have no experience. This is my first project that deals with anything outside of relatively simple code.
 
You could use an FTDI USB-serial cable for the sending PC, then you'd only need one Teensy?
 
I understood that a gamepad = joystick device to send data to the PC is needed?
Not sure how a USB serial device could work here.
 
That's good to know. Can you provide more details?
FTDI make a series of cables that are TTL level UARTs (So suitable for connection directly to a teensy serial port) on one end and USB-A on the other. To the PC they appear to be a COM port just like any other serial device. This would allow you to receive the serial data using a physical serial port on the teensy leaving the teensy USB port available to be configured as a gamepad.

https://ftdichip.com/products/ttl-232r-3v3/ or similar should do the job for you. There are a number of options depending on the connector on the end, whether you want 5V or 3.3V power output etc...

There are lots of ways to go from USB to uart/serial, FTDI cables tend to be popular because 1) of the different USB to serial devices around theirs tend to be the most stable/reliable, the drivers and built into windows as standard now and 2) by building all the required electronics directly into the USB cable it just makes things easy.
 
FTDI make a series of cables that are TTL level UARTs (So suitable for connection directly to a teensy serial port) on one end and USB-A on the other. To the PC they appear to be a COM port just like any other serial device. This would allow you to receive the serial data using a physical serial port on the teensy leaving the teensy USB port available to be configured as a gamepad.

https://ftdichip.com/products/ttl-232r-3v3/ or similar should do the job for you. There are a number of options depending on the connector on the end, whether you want 5V or 3.3V power output etc...

There are lots of ways to go from USB to uart/serial, FTDI cables tend to be popular because 1) of the different USB to serial devices around theirs tend to be the most stable/reliable, the drivers and built into windows as standard now and 2) by building all the required electronics directly into the USB cable it just makes things easy.
Thank you. I'm a complete newbie and have been a bit overwhelmed by all the new terms and ideas.
 
Back
Top