Electrical – Attiny85, reading analog values from PIN3, reports 654 on idle

analogarduinoattiny85buttonc

At first, I am not a hardware professional (starter) so be kind please.

I try to reuse a DENON operation board of a DVD-player with 9 buttons with a Attiny85 Digispark clone connected to PIN3 (see also picture below)

EDIT: About picture: "Sparkfun" must be "Digispark".

enter image description here

enter image description here

However, I can read the values of the buttons, the values seems to be very close so it difficult to detect which button is pressed.

But that's not the main problem/question, the problem is the idle value of analogRead function which I don't understand. The Arduino (IDE) language manual 'says' that it is a value between 0 and 1023. In this case it reports 654 on idle and above when a button is pressed. Tried also PIN1 and reports 1023 but doesn't detect any input (value doesn't change).

Questions:

  1. Why does the analogRead function reports 654 (also when board
    disconnected)
  2. Can I increase the resolution of these values to detect buttons more
    precisely/accurate?

Some code ( I made a USB debugger software solution to debug values via keyboard because there is no UART):

#include "types.h"              // Custom types
#include "TrinketHidCombo.h"    // Trinket USB lib


#define PIN_BUTTON_IN 3

void setDelay( uint16_t ms ) // usbsafe delay
{
  if( ms < 10 )
   { delay(ms); }
  else {
         uint16_t iSteps = ms / 4;

         while( iSteps-- )
         {
           usbIdle(); // We need to do this to keep the Windows USB driver 'sadisfied'
           delay(4);
         }  
       }
  usbIdle();
}  

void usbIdle()
{
  // do nothing, check if USB needs anything done
  TrinketHidCombo.poll();  
}

void usbStart()
{ 
  TrinketHidCombo.begin(); 
}

bool usbSendDebugHandshake()
{
  TrinketHidCombo.pressKey( 0, KEYCODE_F24 ); // press
  TrinketHidCombo.pressKey( 0, 0 ); // release
  setDelay(20);
  TKeyboardLEDState recLedState = usbGetKeyboardLedState();
  return ( recLedState.caps && recLedState.num && recLedState.scroll );
}

void usbDebug(const char* s, bool bLineFeed )
{
 static bool bUsbDebugHandshake = false;
 static bool bUsbDebugEnabled = false;

 if( !bUsbDebugEnabled && !bUsbDebugHandshake )
  { 
    //bUsbDebugHandshake = true;
    bUsbDebugEnabled = bUsbDebugHandshake = usbSendDebugHandshake(); 
  }  


 if(  bUsbDebugEnabled ) 
  { 
    (bLineFeed)?TrinketHidCombo.println( s ):TrinketHidCombo.print( s ); 
    usbIdle();
  }  
}  

void usbDebug(const char* s )
{ usbDebug( s, true ); }

void usbDebug( int i, bool bLineFeed )
{
  char buff[10]; //the ASCII of the integer will be stored in this char array
  memset(buff, 0, sizeof(buff));
  //itoa(i,buff,10); //(integer, yourBuffer, base)
  usbDebug( itoa(i,buff,10), bLineFeed );   
}  


void usbDebug( int i )
{ usbDebug( i, true ); }


TKeyboardLEDState usbGetKeyboardLedState()
{
  uint8_t iState = TrinketHidCombo.getLEDstate();
  TKeyboardLEDState tResult;
  tResult.caps = (iState & KB_LED_CAPS);
  tResult.num = (iState & KB_LED_NUM);
  tResult.scroll = (iState & KB_LED_SCROLL);

  return tResult;
}  

// Setup and main routine 
void setup()
{
  usbStart(); // First priority, start the USB device engine and enumerate

  pinMode(PIN_BUTTON_IN   , INPUT );
}

void loop() // Main program - main()
{
  // Button pressed?
  int iButton = analogRead(PIN_BUTTON_IN);
  usbDebug( "PRESSED: ", false );
  usbDebug( iButton );
  setDelay(1000);
}

Best Answer

I assume you mean a DigiSpark board, not a "ATtiny85 Sparkfun". If you look at the schematics, you see that P3 (being used for USB), has resistors etc connected to it, so even when USB is not in use, it's not suitable for analog input. The only clean pin for analog input seems to be P2.

Furthermore, when using analog input to distinguish a number of buttons, you should never test for exact values. Instead, try to space the voltages produced by the buttons by comfortable margins, and check for ranges instead.