Please be aware of all shipping deadlines before placing your order - we cannot guarantee orders will arrive before Christmas!

ATmega32u4 Input Reading False Low???
Moderators: adafruit_support_bill, adafruit

ATmega32u4 Input Reading False Low???

by SoundGuyAndy on Fri Oct 07, 2011 4:12 pm

Hey guys, I’m in the midst of porting a project from an ATmega328P (compiled via Arduino) to an ATmega32u4 breakout board (via Teensyduino). The program worked fine on the 328, but on the 32u4, I’m having weird issues.

I’ve got Pin F4 set as an input, and pulled up internally. Metering it shows that it does indeed have 5V relative to ground, but the program is reading the port as low.

Code pasted below; this is a troubleshooting build. The problem is on the button referred to as constant "Prev". I replaced the normal code on that input with code that just sets the LED to either red or green depending on input state.

I'm actually having this problem on 3 other inputs as well, while the "Go", "Stop", and "Aux1" inputs are working perfectly fine.

Any ideas what might be wrong?

Thanks,
Andy

Code: Select all | TOGGLE FULL SIZE
#include <MIDI.h>
#include <Debounce.h>
#include <EEPROM.h>




/*
v2.0, build 092511
Port to ATmega32u4 via Teensyduino
Combination MIDI and USB


This section is where the messages sent on each button press/release are defined
 
There are two functions for each button, Press and Release. There is also a ToggleA and ToggleB function for the Aux 1 button.

Messages to be sent during each function should be entered as per the standard Arduino MIDI library or
the Teensyduino USB MIDI library, as appropriate. (Message formats are the same for both)
 
  ex:
    usbMIDI.sendNoteOn(note, velocity, channel)
    usbMIDI.sendNoteOff(note, velocity, channel)
    usbMIDI.sendPolyPressure(note, pressure, channel)
    usbMIDI.sendControlChange(control, value, channel)
    usbMIDI.sendProgramChange(program, channel)
    usbMIDI.sendAfterTouch(pressure, channel)
    usbMIDI.sendPitchBend(value, channel)
    usbMIDI.sendSysEx(length, array)
 
Initially, these are programmed to send a Note On at 127 for each press, and a Note Off for each release, all on channel 1
 */

void PressGo()
{
  usbMIDI.sendNoteOn(0, 127, 1);
  //MIDI.sendNoteOn(0, 127, 1);
  LEDblink();
}

void ReleaseGo()
{
  usbMIDI.sendNoteOff(0, 127, 1);
  //MIDI.sendNoteOff(0, 127, 1);
  LEDblink();
}

void PressPrev()
{
  usbMIDI.sendNoteOn(1, 127, 1);
  //MIDI.sendNoteOn(1, 127, 1);
  LEDblink();
}

void ReleasePrev()
{
  usbMIDI.sendNoteOff(1, 127, 1);
  //MIDI.sendNoteOff(1, 127, 1);
  LEDblink();
}

void PressNext()
{
  usbMIDI.sendNoteOn(2, 127, 1);
  //MIDI.sendNoteOn(2, 127, 1);
  LEDblink();
}

void ReleaseNext()
{
  usbMIDI.sendNoteOff(2, 127, 1);
  //MIDI.sendNoteOff(2, 127, 1);
  LEDblink();
}

void PressStop()
{
  usbMIDI.sendNoteOn(3, 127, 1);
  //MIDI.sendNoteOn(3, 127, 1);
  LEDblink();
}

void ReleaseStop()
{
  usbMIDI.sendNoteOff(3, 127, 1);
  //MIDI.sendNoteOff(3, 127, 1);
  LEDblink();
}

void PressAux1()
{
  usbMIDI.sendNoteOn(4, 127, 1);
  //MIDI.sendNoteOn(4, 127, 1);
  LEDblink();
}

void ReleaseAux1()
{
  usbMIDI.sendNoteOff(4, 127, 1);
  //MIDI.sendNoteOff(4, 127, 1);
  LEDblink();
}

void ToggleA()
{
  usbMIDI.sendNoteOn(5, 127, 1);
  //MIDI.sendNoteOn(5, 127, 1);
  LEDgreenON();
}

void ToggleB()
{
  usbMIDI.sendNoteOff(5, 127, 1);
  //MIDI.sendNoteOff(5, 127, 1);
  LEDredON();
}

void PressAux2()
{
  usbMIDI.sendNoteOn(5, 127, 1);
  //MIDI.sendNoteOn(5, 127, 1);
  LEDblink();
}

void ReleaseAux2()
{
  usbMIDI.sendNoteOff(5, 127, 1);
  //MIDI.sendNoteOff(5, 127, 1);
  LEDblink();
}

void PressFoot()
{
  usbMIDI.sendNoteOn(6, 127, 1);
  //MIDI.sendNoteOn(6, 127, 1);
  LEDblink();
}

void ReleaseFoot()
{
  usbMIDI.sendNoteOff(6, 127, 1);
  //MIDI.sendNoteOff(6, 127, 1);
  LEDblink();
}



//Global declarations and other general housekeeping

int DoubleGoWindow;
#define DoubleGoDefault 250 //Value (in ms) for Double Go protection
#define DebounceVal 60 //Value (in ms) for regular debounce

#define LEDbrightness 2 // Set analog level (0-255) for LED


#define Go PIN_B0
#define Prev PIN_F4
#define Next PIN_B4
#define Stop PIN_B3
#define Aux1 PIN_D2
#define Aux2 PIN_F7
#define Foot PIN_D7
#define FootLED PIN_D6



#define LEDgreen PIN_B6
#define LEDred PIN_B7

//define variables for soft mode selection
int FootMode;
int AuxMode;


//define constants for tracking LED status, green=0, red=1
#define green 0
#define red 1

//define constants for Aux Mode and Footswitch Mode
#define aux 1
#define gpo 0
#define independent 1
#define mirror 0

//define constants for tracking contact closure, open=1, closed=0
#define open 0
#define closed 1

//define constants for button status values, inputs are using pull-ups, so pressed=LOW (0), released=HIGH (1)
#define pressed 0
#define released 1

//set variables for tracking button statuses, etc

unsigned long TimeOfLastGo = millis() - DoubleGoWindow;
unsigned long TimeOfLastGoRelease = millis() - DoubleGoWindow;
unsigned long TimeOfLastFootPress = millis() - DoubleGoWindow;
unsigned long TimeOfLastFootRelease = millis() - DoubleGoWindow;
unsigned long currentMillis = millis();
int LastGoSent = released;
//Set TimeOfLastGo so that first go can go instaneously. Never likely to be needed, but let's dot t's and cross i's

int CurrentGo=1;
int CurrentPrev=1;
int CurrentNext=1;
int CurrentStop=1;
int CurrentAux1=1;
int CurrentAux2=1;
int CurrentFoot=1;

int ChangedGo=0;
int ChangedPrev=0;
int ChangedNext=0;
int ChangedStop=0;
int ChangedAux1=0;
int ChangedAux2=0;
int ChangedFoot=0;

int InitialFoot;

byte CurrentContactState;
byte LastAux2=released;

byte CurrentLED;

// Constants for EEPROM addresses
#define EEPROMgpo 0
#define EEPROMaux 1
#define EEPROMfoot 2
#define EEPROMdoublego 3 //this value will be stored in two bytes, ending up in 3 and 4

//Set up debounce objects
Debounce debounceGo = Debounce( DebounceVal , Go ); // Initiate a debounce object for Go pin, with a 20 ms debounce time
Debounce debouncePrev = Debounce( DebounceVal , Prev ); // Initiate a debounce object for Prev pin, with a 20 ms debounce time
Debounce debounceNext = Debounce( DebounceVal , Next ); // Initiate a debounce object for Next pin, with a 20 ms debounce time
Debounce debounceStop = Debounce( DebounceVal , Stop ); // Initiate a debounce object for Stop pin, with a 20 ms debounce time
Debounce debounceAux1 = Debounce( DebounceVal , Aux1 ); // Initiate a debounce object for Aux1 pin, with a 20 ms debounce time
Debounce debounceAux2 = Debounce( DebounceVal , Aux2 ); // Initiate a debounce object for Aux2 pin, with a 20 ms debounce time
Debounce debounceFoot = Debounce( DebounceVal , Foot ); //Initiate a debounce object for Footswitch pin, with a 20 ms debounce time

//++++++++++++++++++++++++++++++++++++
void LEDgreenON()
{
  analogWrite(LEDgreen, LEDbrightness);
  digitalWrite(LEDred, LOW);
  CurrentLED=green;
}


//++++++++++++++++++++++++++++++++++++
void LEDredON()
{
  analogWrite(LEDred, LEDbrightness);
  digitalWrite(LEDgreen, LOW);
  CurrentLED=red;
}


//++++++++++++++++++++++++++++++++++++
void LEDoff()
{
  digitalWrite(LEDgreen, LOW);
  digitalWrite(LEDred, LOW);
}


//++++++++++++++++++++++++++++++++++++
void LEDtoggle(){
  //LED is a bi-color LED, color determined by which pin is on (high); both pins the same (either high or low) turns it off
LEDoff();
  if (CurrentLED==green)
  {
    LEDredON();
  }
  else
  {
    LEDgreenON();
  }

}


//++++++++++++++++++++++++++++++++++++
void LEDblink()
{
  //blinks LED opposite color for 50 ms
  LEDtoggle();
  delay(50);
  LEDtoggle();


  /* Commenting out for more tidy method using LEDtoggle()
   if (CurrentLED==green){
   digitalWrite(LEDgreen, LOW);
   digitalWrite(LEDred, HIGH);
   delay(20);
   digitalWrite(LEDgreen, HIGH);
   digitalWrite(LEDred, LOW);
   }
   else
   {
   digitalWrite(LEDgreen, HIGH);
   digitalWrite(LEDred, LOW);
   delay(20);
   digitalWrite(LEDgreen, LOW);
   digitalWrite(LEDred, HIGH);
   }
   */
}



//++++++++++++++++++++++++++++++++++++


//Next two functions add support for writing/reading integers to EEPROM
void EEPROMWriteInt (int address, unsigned int integer)
   {
   EEPROM.write(address, highByte(integer));
   EEPROM.write(address + 1, lowByte(integer));
   }

unsigned int EEPROMReadInt (int address)
   {
   unsigned int higherByte = EEPROM.read(address);
        unsigned int lowerByte = EEPROM.read(address + 1);
        return (word (higherByte, lowerByte));
   }

void setup() {

  //MIDI.begin();
 
 
  //Set each input pin to input mode
  //Setting the input is technically redundant, as this is the default, but let's do it to be consistent
  pinMode(Go, INPUT_PULLUP);
  pinMode(Prev, INPUT_PULLUP);
  pinMode(Next, INPUT_PULLUP);
  pinMode(Stop, INPUT_PULLUP);
  pinMode(Aux1, INPUT_PULLUP);
  pinMode(Aux2, INPUT_PULLUP);
  pinMode(Foot, INPUT_PULLUP);
  //pinMode(Contact, OUTPUT);
  // pinMode(FootMode, INPUT); //commented out with switch to soft mode selection on startup
  // pinMode(AuxMode, INPUT); // same as above
  pinMode(LEDgreen, OUTPUT);
  pinMode(LEDred, OUTPUT);
 
  delay (100); //trying delay to give time for inputs to initialize
 
 
  //set add'l grounds
  pinMode(PIN_E6, OUTPUT);
  digitalWrite(PIN_E6, LOW);
 
  pinMode(PIN_B2, OUTPUT);
  digitalWrite(PIN_B2, LOW);
 
  pinMode(PIN_D1, OUTPUT);
  digitalWrite(PIN_D1, LOW);
 
  pinMode(PIN_C7, OUTPUT);
  digitalWrite(PIN_C7, LOW);
 
  pinMode(PIN_F5, OUTPUT);
  digitalWrite(PIN_F5, LOW);
 

  //set 5V for footswitch LED
  pinMode(FootLED, OUTPUT);
  digitalWrite(FootLED, HIGH);

   
 
LEDgreenON();
 
//Sense polarity for Footswitch
InitialFoot=digitalRead(Foot);

/* REM out to test without startup functions

   //Check for Aux mode setting change on startup
  CurrentAux1=digitalRead(Aux1);
  CurrentAux2=digitalRead(Aux2);

  if (CurrentAux1==pressed){
    EEPROM.write(EEPROMaux, aux);
    LEDredON();
    delay(1000);
    LEDgreenON();
  }

  if (CurrentAux2==pressed){
    EEPROM.write(EEPROMaux, gpo);
   LEDredON();
    delay(1000);
   LEDgreenON();
    delay(1000);
   LEDredON();
    delay(1000);
   LEDgreenON();
  }
 
 
 
  //Check for/set custom double go window
  CurrentPrev=digitalRead(Prev);
  CurrentNext=digitalRead(Next);
 
  if (CurrentPrev==pressed && CurrentNext==pressed){
    int x=0;
    while(x < 2){
      if (x==0) {
        LEDtoggle();
      }
     
      CurrentGo=digitalRead(Go);

     
      if(CurrentGo==pressed && x==0){
        TimeOfLastGo = millis();
        LEDgreenON();
        x=1;
      }
     
      if(CurrentGo==released && x==1){
        currentMillis = millis();
        DoubleGoWindow = currentMillis - TimeOfLastGo;
        EEPROMWriteInt (EEPROMdoublego, DoubleGoWindow);
        x=2;
        LEDredON();
      }
    }
  }
       

  //Check for Footswitch mode setting change and default Double Go reset on startup
  CurrentGo=digitalRead(Go);
  CurrentStop=digitalRead(Stop);

  if (CurrentGo==pressed && CurrentStop==pressed){
      DoubleGoWindow=DoubleGoDefault;
      EEPROMWriteInt (EEPROMdoublego, DoubleGoWindow);
    LEDoff();
     delay(1000);
    LEDredON();
     delay(1000);
    LEDoff();
     delay(1000);
    LEDgreenON();
}
  if (CurrentGo==pressed && CurrentStop==released){
    EEPROM.write(EEPROMfoot, mirror);
   LEDredON();
    delay(1000);
   LEDgreenON();
    delay(1000);
   LEDredON();
    delay(1000);
   LEDgreenON();
    delay(1000);
    LEDredON();
    delay(1000);
   LEDgreenON();
  }
 

  if (CurrentStop==pressed && CurrentGo==released){
    EEPROM.write(EEPROMfoot, independent);
   LEDredON();
    delay(1000);
   LEDgreenON();
    delay(1000);
    LEDredON();
    delay(1000);
   LEDgreenON();
    delay(1000);
    LEDredON();
    delay(1000);
   LEDgreenON();
    delay(1000);
    LEDredON();
    delay(1000);
   LEDgreenON();
  }

  //Read footswitch and aux modes, Double Go from EEPROM, store as variables available to program


  FootMode = EEPROM.read(EEPROMfoot);
  AuxMode = EEPROM.read(EEPROMaux);
  DoubleGoWindow = EEPROMReadInt (EEPROMdoublego);

//  Check previous state of Aux if in GPO mode from EEPROM, and reset current state if remote is in GPO mode
  if (AuxMode==gpo){
    CurrentContactState = EEPROM.read(EEPROMgpo);
    if (CurrentContactState==closed){
      LEDredON();
    }
    else{
      LEDgreenON();}}
    else{LEDgreenON();}
  //}
  */
}

void loop() {

  /*
To read buttons, first update debouncer, then read it into a variable:
   
   debouncer.update();   <--This will optionally return a "true" if status has changed since last read
   variable=debouncer.read()
   */

  //Update the debouncers to see whether their state has changed since the last check (filtered by debounce time):
  ChangedGo = debounceGo.update();
  ChangedPrev = debouncePrev.update();
  ChangedNext = debounceNext.update();
  ChangedStop = debounceStop.update();
  ChangedAux1 = debounceAux1.update();
  ChangedAux2 = debounceAux2.update();
  ChangedFoot = debounceFoot.update();

  if (ChangedGo==true){ //If there's been a change of state in the Go button
    CurrentGo = debounceGo.read(); //read the current state into a variable
    currentMillis = millis(); //read the current timestamp into a temporary variable
    if (CurrentGo==pressed && currentMillis - TimeOfLastGo >= DoubleGoWindow){   
           
      // if the current state of the button is pressed *AND* it's been longer than the Double Go Protection window
     PressGo();
 
      //update tracking variables
      TimeOfLastGo = millis();
      LastGoSent = pressed;
      }       
    else{ 
           //Otherwise, it's just been released, so...
           if (CurrentGo==released && /*LastGoSent==pressed &&*/ currentMillis-TimeOfLastGoRelease >= DoubleGoWindow){     
      ReleaseGo();
      TimeOfLastGoRelease = millis();
      LastGoSent = released;
      }
    }
  }  //send the ReleaseGo Message

  //Remaining buttons follow the same pattern, so I'm not going to explicitly comment them

  //if (ChangedPrev==true){
    //CurrentPrev = debouncePrev.read();
    CurrentPrev = digitalRead(Prev);
    LEDoff(); // for testing purposes
    if (CurrentPrev==pressed){
     //PressPrev();
       LEDredON();
    }
    else{
      //ReleasePrev();
       LEDgreenON();
     }
  //}


  if (ChangedNext==true){
    CurrentNext = debounceNext.read();
    if (CurrentNext==pressed){
      PressNext();
    }
    else{
      ReleaseNext();
    }
  }


  if (ChangedStop==true){
    CurrentStop = debounceStop.read();
    if (CurrentStop==pressed){
      PressStop();
    }
    else{
      ReleaseStop();
    }
  }


  if (ChangedFoot==true){
    CurrentFoot = debounceFoot.read();
   
    //This can be cleaned up by testing for DoubleGoWindow first, then footswitch mode
   
    if (CurrentFoot!=InitialFoot){ //if Footswitch is pressed, ie opposite of initial state
      if (FootMode==independent && currentMillis - TimeOfLastFootPress >=DoubleGoWindow ){   //if Footswitch input is set to have its own message
        PressFoot();
        TimeOfLastFootPress = millis();
      }        //send that message
      else{ if (currentMillis-TimeOfLastFootPress >= DoubleGoWindow){                      //if Footswitch input is set to mirror the Go button
        PressGo();
        TimeOfLastFootPress = millis();}
      }
    }        //send the Go message
   
    else{
      if (FootMode==independent && currentMillis - TimeOfLastFootRelease >= DoubleGoWindow){
        ReleaseFoot();
        TimeOfLastFootRelease = millis();
      }
      else{
        if (currentMillis - TimeOfLastFootRelease >= DoubleGoWindow){
        ReleaseGo();
        TimeOfLastFootRelease=millis();}
      }
    }
  }

if (AuxMode==aux){
  if (ChangedAux1==true){
      CurrentAux1 = debounceAux1.read();
    if (CurrentAux1==pressed){
      PressAux1();
    }
    else{
      ReleaseAux1();
    }}}
   
if (AuxMode==gpo){
  if (ChangedAux1==true)
  {
    CurrentAux1 = debounceAux1.read();
    if (CurrentAux1==pressed){
     if (CurrentContactState==open){
       CurrentContactState = closed;
       EEPROM.write(EEPROMgpo, closed);
       ToggleB();
     }
       else{
        CurrentContactState = open;
        EEPROM.write(EEPROMgpo, open);
        ToggleA();
      }
   }}}


  if (ChangedAux2==true){
      CurrentAux2 = debounceAux2.read();
    if (CurrentAux2==pressed){
      PressAux2();
    }
    else{
      ReleaseAux2();
    }
  }
}

// END OF MAIN PROGRAM
SoundGuyAndy
 
Posts: 4
Joined: Fri Oct 07, 2011 4:11 pm

Re: ATmega32u4 Input Reading False Low???

by SoundGuyAndy on Fri Oct 07, 2011 8:52 pm

Turns out it's an obscure bug in Teensyduino. Paul's sent me a workaround to try, and is going to publish a fix in the next day or so.

--A
SoundGuyAndy
 
Posts: 4
Joined: Fri Oct 07, 2011 4:11 pm

Re: ATmega32u4 Input Reading False Low???

by shahriar_pollob on Tue Aug 28, 2012 7:18 pm

Hi,

I don't know if this is the correct place to post it. I was using a atmega32u4 breakout board from sparkfun which has a modified LUFA CDC bootloader. I have a very program written to it.

Code: Select all | TOGGLE FULL SIZE
#define set_bit(address,bit) (address |= (1<<bit))
#define clear_bit(address,bit) (address &= ~(1<<bit))
#define toggle_bit(address,bit) (address ^= (1<<bit))
#define check_bit(address,bit) ((address & (1<<bit)) == (1<<bit))

int main(void)
{
    set_bit(DDRB,0);
    set_bit(DDRB,1);

    clear_bit(DDRF,7);
    set_bit(PORTF,7);

    while(1)
    {
        if(check_bit(PINF,7))
        {
            set_bit(PORTB,1);
        }
        else
        {
            set_bit(PORTB,0);
        }

        _delay_ms(1000);
    }

    return 0;
}


So, the code checks PF7 every second and sets PB0 or PB1 according to the state of PF7. This works fine in the sparkfun board. I then got a fresh atmega32u4 chip and made the same board myself and programmed the same code using the existing factory-made DFU bootloader. But for some reason, PF7 is always reading a false low. Same case for PF4,5 and 6. PF0 and PF1 works fine. Like you, I've also checked the actual voltage on these pins.

Have you found any solution to this? Is this because of the bootloader?
shahriar_pollob
 
Posts: 1
Joined: Tue Aug 28, 2012 7:12 pm

Re: ATmega32u4 Input Reading False Low???

by adafruit_support_bill on Wed Aug 29, 2012 5:35 am

I was using a atmega32u4 breakout board from sparkfun

Have you posted your question to Sparkfun? They are the best qualified to support their own products.
User avatar
adafruit_support_bill
 
Posts: 32638
Joined: Sat Feb 07, 2009 10:11 am