Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: Momentary Buttons Work Sporadically When Connected To Battery. 100% On USB

  1. #1

    Momentary Buttons Work Sporadically When Connected To Battery. 100% On USB

    Basically as my title says. I have to momentary buttons wired to my Teensy 3.5, on Pins 32 and 34, sharing a common ground where the battery is connected to. I have also moved their ground to a pin that wasn't the same one the battery was on. I am using this schematic as a reference, with my only changes being that every ground is connected to the topmost ground pin on the teensy and I have a 4 pin Male/Female connector as opposed to a 5 pin.

    Click image for larger version. 

Name:	4f6a4cf1576e4fcda24785b415f37ce0c3ec90ad.png 
Views:	22 
Size:	24.9 KB 
ID:	19138

    I uploaded a simple file that turns on the built in LED when my main button is pressed, and when connected to USB power via my computer, it works just fine. But when connected to my battery, the LED will stay on when I left go of the button, seemingly until whenever it wants to stop. Sometimes twisting my JST cables shuts it off, sometimes it's just a few seconds; I have no idea why.

    I use a 5 pin JST connector to connect the 5 pins to that male connector in the schematic (Power up, Power down, Ground from battery, Ground from plug to teensy, and data.) The 2 grounds are sliced together on the other end before merging into one cable that connectors to the radial connector.

    My only thought is that there is something wrong with that wiring on my 5 pin connector. Or that the battery is much more drained than I had thought and I haven't assembled my charger yet to charge it. Any thoughts would be greatly appreciated! Thank you!

    Full Source Code and my git repo if you'd rather look at it there:

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <WS2812Serial.h>
    #include "MPU9250.h"
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav playSdWav3;     //xy=154,392
    AudioPlaySdWav playSdWav2;     //xy=159,355
    AudioPlaySdWav playSdWav1;     //xy=384,2003
    AudioMixer4 mixer1;            //xy=456,406
    AudioOutputTDM tdm1;           //xy=558,2017
    AudioOutputAnalogStereo dacs1; //xy=659,403
    AudioConnection patchCord3(playSdWav2, 0, mixer1, 1);
    AudioConnection patchCord4(playSdWav2, 1, mixer1, 0);
    AudioConnection patchCord5(playSdWav1, 0, mixer1, 2);
    AudioConnection patchCord6(playSdWav1, 1, mixer1, 3);
    AudioConnection patchCord7(mixer1, 0, dacs1, 0);
    AudioConnection patchCord8(mixer1, 0, dacs1, 1);
    // GUItool: end automatically generated code
    
    #define onOffButton PIN_A13
    #define colorButton PIN_A15
    #define SDCARD_CS_PIN BUILTIN_SDCARD
    #define SDCARD_MOSI_PIN 11 // not actually used
    #define SDCARD_SCK_PIN 13  // not actually used
    #define PIN 1
    //Colors
    #define OFFCOLOR 0x000000
    #define GREEN 0x17ff00
    #define RED 0xFF0000
    #define BLUE 0x12e3f0
    #define PURPLE 0x9c11cc
    #define PINK 0xe359c7
    #define YELLOWORANGE 0xef8d0f
    #define WHITE 0xffffff
    
    const int numled = 144;
    int previousMillisInterrupt = 0;
    int previousMillisAccel = 0;
    int currentMillisAccel = 0;
    int xSwingThresholdPositive = 3;
    int zSwingThresholdPositive = 3;
    int xSwingThresholdNegative = -3;
    int zSwingThresholdNegative = -3;
    int clashThreshold = 28;
    int clashThresholdNegative = -28;
    int colorFlag = 0;
    //How many colors do we have, with the exception of OFF
    const int NUMOFCOLORS = 7;
    int colorInUse = GREEN; //Green by default
    
    int function = 0; //what action are we going to perform
    int status = 0;   //global status int we can use for initializations and usages
    
    byte drawingMemory[numled * 3];         //  3 bytes per LED
    DMAMEM byte displayMemory[numled * 12]; // 12 bytes per LED
    
    WS2812Serial leds(numled, displayMemory, drawingMemory, PIN, WS2812_GRB);
    MPU9250 IMU(Wire, 0x68);
    
    void buttonPress()
    {
      unsigned long currentMillisInterrupt = millis();
      if (currentMillisInterrupt - previousMillisInterrupt >= 1000)
      {
        function++;
        Serial.print("Function is now: ");
        Serial.println(function);
    
        if (function >= 4)
        {
          function = 0;
        }
        previousMillisInterrupt = currentMillisInterrupt;
      }
    }
    
    void switchColors()
    {
      byte colorByte = 0;
    
      Serial.println("Switching colors");
    
      colorFlag++;
      if (colorFlag > NUMOFCOLORS)
      {
        colorFlag = 0;
      }
      colorByte = 1;
    
      switch (colorFlag)
      {
        //GREEN
      case 0:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, GREEN);
            leds.setPixel(i + 1, GREEN);
            i++;
            leds.show();
          }
          colorInUse = GREEN;
          colorByte = 0;
        }
        break;
        //BLUE
      case 1:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, BLUE);
            leds.setPixel(i + 1, BLUE);
            i++;
            leds.show();
          }
          colorInUse = BLUE;
          colorByte = 0;
        }
        break;
        //RED
      case 2:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, RED);
            leds.setPixel(i + 1, RED);
            i++;
            leds.show();
          }
          colorInUse = RED;
          colorByte = 0;
        }
        break;
        //PURPLE
      case 3:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, PURPLE);
            leds.setPixel(i + 1, PURPLE);
            i++;
            leds.show();
          }
          colorInUse = PURPLE;
          colorByte = 0;
        }
        break;
        //PINK
      case 4:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, PINK);
            leds.setPixel(i + 1, PINK);
            i++;
            leds.show();
          }
          colorInUse = PINK;
          colorByte = 0;
        }
        break;
      case 5:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, YELLOWORANGE);
            leds.setPixel(i + 1, YELLOWORANGE);
            i++;
            leds.show();
          }
          colorInUse = YELLOWORANGE;
          colorByte = 0;
        }
        break;
      case 6:
        if (colorByte == 1)
        {
          for (int i = 1; i < numled; i++)
          {
            leds.setPixel(i, WHITE);
            leds.setPixel(i + 1, WHITE);
            i++;
            leds.show();
          }
          colorInUse = WHITE;
          colorByte = 0;
        }
        break;
      }
    }
    
    void setup()
    {
      // put your setup code here, to run once:
      Serial.println("Setup start");
      Serial.begin(9600);
    
      //Set LEDs to Off
      leds.begin();
      for (int i = numled; i > -10; i--)
      {
        leds.setPixel(i, OFFCOLOR);
        leds.show();
      }
      leds.show();
    
      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(onOffButton, INPUT);
      pinMode(colorButton, INPUT);
      delay(250);
    
      // start communication with IMU
      status = IMU.begin();
      if (status < 0)
      {
        Serial.println("IMU initialization unsuccessful");
        Serial.println("Check IMU wiring or try cycling power");
        Serial.print("Status: ");
        Serial.println(status);
        while (1)
        {
        }
      }
    
      AudioMemory(8);
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN)))
      {
        while (1)
        {
          Serial.println("Unable to access the SD card");
          delay(500);
        }
      }
      mixer1.gain(0, 0.1f);
      mixer1.gain(1, 0.1f);
    
      attachInterrupt(digitalPinToInterrupt(onOffButton), buttonPress, FALLING);
      attachInterrupt(digitalPinToInterrupt(colorButton), switchColors, FALLING);
    
      Serial.println(playSdWav1.isPlaying() ? "TRUE" : "FALSE");
      if (playSdWav1.isPlaying() == false)
      {
        Serial.println("Playing startup sound");
        playSdWav1.play("SETUP.WAV");
        delay(1000); // wait for library to parse WAV info
      }
    
      Serial.println("Setup complete");
    }
    
    //Empty, because it stays off (I'd unplug the battery here to save power)
    void stayOff() {}
    
    void turnOn()
    {
      digitalWrite(LED_BUILTIN, HIGH);
    
      if (playSdWav1.isPlaying() == false)
      {
        Serial.println("Playing on sound");
        playSdWav1.play("POWERON.WAV");
        //Seems this value is dependent on how long my ignition sound is
        delay(10);
        // Don't play sound here. It overrides the ignition for some reason
        //  playSdWav2.play("HUM.WAV");
        //  delay(10);
      }
    
      for (int i = 1; i < numled; i++)
      {
        leds.setPixel(i, colorInUse);
        leds.setPixel(i + 1, colorInUse);
        i++;
        leds.show();
      }
    
      function = 2;
    }
    
    void turnOff()
    {
      digitalWrite(LED_BUILTIN, LOW);
    
      Serial.println("Playing off sound");
      playSdWav1.play("POWEROFF.WAV");
      delay(10);
    
      for (int i = numled; i > -10; i--)
      {
        leds.setPixel(i, OFFCOLOR);
        leds.show();
      }
    
      function = 0;
    }
    
    void swing()
    {
      int index = random(0, 15);
    
      const char *swing = "";
    
      switch (index)
      {
      case 0:
        swing = "SWING1.WAV";
        break;
      case 1:
        swing = "SWING2.WAV";
        break;
      case 2:
        swing = "SWING3.WAV";
        break;
      case 3:
        swing = "SWING4.WAV";
        break;
      case 4:
        swing = "SWING5.WAV";
        break;
      case 5:
        swing = "SWING6.WAV";
        break;
      case 6:
        swing = "SWING7.WAV";
        break;
      case 7:
        swing = "SWING8.WAV";
        break;
      case 8:
        swing = "SWING8.WAV";
        break;
      case 9:
        swing = "SWING10.WAV";
        break;
      case 10:
        swing = "SWING11.WAV";
        break;
      case 11:
        swing = "SWING12.WAV";
        break;
      case 12:
        swing = "SWING13.WAV";
        break;
      case 13:
        swing = "SWING14.WAV";
        break;
      case 14:
        swing = "SWING15.WAV";
        break;
      case 15:
        swing = "SWING16.WAV";
        break;
      default:
        swing = "SWING1.WAV";
        break;
      }
    
      if (playSdWav2.isPlaying() == false)
      {
        Serial.print("Playing swing sound: ");
        Serial.println(swing);
        playSdWav1.play(swing);
        delay(10);
      }
    }
    
    void clash()
    {
      int index = random(0, 2);
      const char *clash = "";
    
      switch (index)
      {
      case 0:
        clash = "CLASH1.WAV";
        break;
      case 1:
        clash = "CLASH2.WAV";
        break;
      case 2:
        clash = "CLASH3.WAV";
        break;
      }
    
      if (playSdWav2.isPlaying() == false)
      {
        Serial.println("Playing clash sound");
        playSdWav1.play(clash);
        delay(10);
      }
    }
    
    void readAccelerometer()
    {
      IMU.readSensor();
    
      float gyroX = IMU.getGyroX_rads();
      float gyroZ = IMU.getGyroZ_rads();
      float accelerationTotal = IMU.getAccelX_mss() + IMU.getAccelY_mss() + IMU.getAccelZ_mss();
    
      // Serial.print("Accelertaion Total: " );
      // Serial.println(accelerationTotal, 6);
    
      if (accelerationTotal >= clashThreshold || accelerationTotal <= clashThresholdNegative)
      {
        Serial.println("We've clashed");
        clash();
      }
    
      if (gyroX >= xSwingThresholdPositive || gyroX <= xSwingThresholdNegative)
      {
        Serial.println("SWINGING!");
        swing();
      }
      if (gyroZ >= zSwingThresholdPositive || gyroZ <= zSwingThresholdNegative)
      {
        Serial.println("SWINGING!");
        swing();
      }
    
      delay(100);
    }
    
    void poweredOn()
    {
      if (playSdWav1.isPlaying() == false)
      {
        Serial.println("Playing HUM sound");
        playSdWav1.play("HUM.WAV");
        delay(10);
      }
    
      readAccelerometer();
    }
    
    void loop()
    {
    
      // switchColors();
      // put your main code here, to run repeatedly:
      switch (function)
      {
      case 0:
        stayOff();
        break;
      case 1:
        turnOn();
        break;
      case 2:
        poweredOn();
        break;
      case 3:
        turnOff();
        break;
      default:
        break;
      }
    }
    Last edited by Matt The Gamer; 02-22-2020 at 02:31 PM.

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,333
    Sometimes hard to say without actually seeing your actual program?

    Example things to check:
    How are your defining these pins and checking them?

    Are they defined as INPUT_PULLUP? and you are checking for them to go low?

    Are you using the bounce like library to handle case of signal bouncing up and down?


    Does your code have in it something like: while (!Serial) ;
    which would hang forever when you are plugged into battery but not serial?

    Or another variation of:
    Code:
    elapsedMillis em = 0;
    while (!Serial && (em < 3000)) ;
    Which would wait for 3 seconds every time it is called for the Serial object to be available...
    (elapsedMillis can also be replaced by saving start time and doing your own millis()-start_time...

    Or??? again can only throw darts.

  3. #3
    Sometimes hard to say without actually seeing your actual program?
    Right, sorry. I'll update my original Post with the full code.

    How are your defining these pins and checking them?
    Are they defined as INPUT_PULLUP? and you are checking for them to go low?
    See my edit in the main post for code. But they are defined as #define variables and then called with just INPUT, not INPUT_PULLUP. They have interrupts attached to trigger their respective functions during loop().

    Are you using the bounce like library to handle case of signal bouncing up and down?
    I don't believe so no. I've never heard of that before.

    Does your code have in it something like: while (!Serial) ;
    which would hang forever when you are plugged into battery but not serial?

    Or another variation of:
    And no. None of that

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,473
    Any chance you're running all of Teensy's current though extremely thin, low-quality wires? Like these...

    Click image for larger version. 

Name:	cheapwires.jpg 
Views:	5 
Size:	61.1 KB 
ID:	19139

    If you have wires like this, try measuring them with an ohm meter. Some are so thin, so poorly constructed that they'll measure several ohms. If you run a pulsing current that averages 50 to 100 mA, where the brief pulses are much higher, it's pretty easy to get large changes in voltage due to the high resistance of the hair-thin wire.

  5. #5
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,244
    The 2 grounds are sliced together
    I presume this should be "spliced". If the ground wires are only twisted together, they probably aren't making good electrical contact. They should be soldered. Twisting the JST cables may cause the spliced grounds to glitch.


    A few notes about your code:

    - you never use playSdWav3

    - The default gain for mixer inputs is 1 so the total gain for mixer1 is 2.2 (because 2 and 3 are 1 each). It would be best to keep the total gain to no more than 1. Set the gains for inputs 2 and 3 on the mixer1 to 0.4

    - although you don't explicitly use debouncing, your buttonPress function responds to a button press no more than once a second so contact bounce shouldn't be a problem.

    - I presume that case 8 should use SWING9.WAV

    - random(0,15) will produce numbers from 0 to 14, so "case 15:" will never be reached. You need random(0, 16).

    Pete

  6. #6
    Senior Member
    Join Date
    Nov 2017
    Location
    Belgium
    Posts
    215
    Quote Originally Posted by KurtE View Post
    How are your defining these pins and checking them?
    Are they defined as INPUT_PULLUP? and you are checking for them to go low?
    Quote Originally Posted by Matt The Gamer View Post
    See my edit in the main post for code. But they are defined as #define variables and then called with just INPUT, not INPUT_PULLUP. They have interrupts attached to trigger their respective functions during loop().
    You definitively need pullup resistors on those pins!

  7. #7
    Quote Originally Posted by PaulStoffregen View Post
    Any chance you're running all of Teensy's current though extremely thin, low-quality wires? Like these...

    Click image for larger version. 

Name:	cheapwires.jpg 
Views:	5 
Size:	61.1 KB 
ID:	19139

    If you have wires like this, try measuring them with an ohm meter. Some are so thin, so poorly constructed that they'll measure several ohms. If you run a pulsing current that averages 50 to 100 mA, where the brief pulses are much higher, it's pretty easy to get large changes in voltage due to the high resistance of the hair-thin wire.
    Replaced the connector's wires with stronger 18 gauge (as opposed to the 26 it was before) and it's the same result unfortunately :/.

  8. #8
    Quote Originally Posted by neurofun View Post
    You definitively need pullup resistors on those pins!
    I will look into getting some resistors to see if it helps. Why are they needed though? And that's not a snarky "but why" statement. This is my first project with an arduino/teensy so I'm genuinely curious as to why they're needed since they work just fine on USB power and not battery.

  9. #9
    Quote Originally Posted by Matt The Gamer View Post
    I will look into getting some resistors to see if it helps. Why are they needed though? And that's not a snarky "but why" statement. This is my first project with an arduino/teensy so I'm genuinely curious as to why they're needed since they work just fine on USB power and not battery.
    On that topic, switching the button's read to INPUT_PULLUP seems to have fixed my issue. At least at a first glance. Does the 3.5 have internal pullup resistors? I couldn't find any definitive answer to that..

  10. #10
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,244
    Yes, it does.

    Pete

  11. #11
    Senior Member
    Join Date
    Nov 2017
    Location
    Belgium
    Posts
    215
    Quote Originally Posted by Matt The Gamer View Post
    I will look into getting some resistors to see if it helps. Why are they needed though? And that's not a snarky "but why" statement. This is my first project with an arduino/teensy so I'm genuinely curious as to why they're needed since they work just fine on USB power and not battery.
    Without a pullup resistor the input pin is connected to nothing(floating), its state is undefined and influenced by different factors. Simply put, the wire attached to the pin acts like an antenna.

    By adding an external pullup resistor or enabling the internal one, the input pin's state is set to high(3.3V).
    If I'm not mistaken, all pins that can act as a digital pin have an internal pullup and pulldown resistor available.

    The fact that it worked with USB might just be a lucky occurrence.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •