0
\$\begingroup\$

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);
}
\$\endgroup\$
6
  • \$\begingroup\$ Do you have a schematic of the Denon board? I suspect you might need a ground connection between the ATTiny and the Denon board - but I'd need to see a schematic to be sure. \$\endgroup\$ Jun 23, 2016 at 3:53
  • \$\begingroup\$ Thanks for your comment. Schematic is here - manualslib.com/manual/906697/… but schematic is unreadable. Do you really think grounding explained why the analogRead function returns 654 without board attached? Or do you want to figure out the close values? \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 5:26
  • \$\begingroup\$ The schematic seems to be different to this board. There are five pins not seven and there are SMD resistors for each button. Two groups of buttons (marked red and green). Two pins are not used. Two groups of buttons (two wires) with shared ground. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 18:26
  • \$\begingroup\$ Just added correct schematic \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 19:44
  • \$\begingroup\$ It still looks like you don't have the correct schematic - you say your board has five pins, with two unused, but the schematic shown now has four pins, all used. \$\endgroup\$ Jun 23, 2016 at 23:32

2 Answers 2

2
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\begingroup\$ Thanks for the answer and schematic, it's a DigiSpark, changed it already. Search allot, that's the reason of confusion ;-) About schematic and pins: That's really sad to know because P2 and P0) is already being used by a rotary encoder (not listed in code). I know i cannot use P5 (RESET) without a bootloader update. The pins are a little confusing, pins called P0 etc on board and in schematic it shows 1-6. So there is only one pin that can be used analog. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 5:53
  • \$\begingroup\$ Second paragraph: I know that I must check ranges, because it can easily differ when using other cables etc. As you can notice in the picture, the measured values are very close and overlap. Can I increase the resolution of these values to detect buttons more precisely/accurate? \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 5:57
  • \$\begingroup\$ I will try the P2 and come back later with results ;-) \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 6:00
  • \$\begingroup\$ When I connect the board to PB2, it reads only 0. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 19:13
3
\$\begingroup\$

As @microtherion has said, there are components on PB3. Mainly, a pull-up to 5V, a pull-down 3.6V Zener Diode, and a current limiting series resistor. This is for the USB D- line. PB4 has just the Zener and a series resistor, for the USB D+ line. These components are to keep the USB lines within voltage specs for the Data lines (which are not 5V, that's just USB power), and to signal to whatever host that it connects to that there is a USB device inserted.

Considering the ADC is set to full voltage range of 5V, with 0V corresponding to a result of 0, and 5V a result of 1023, a result of 654 is roughly 3.2V sensed at the Analog Input.

As the line is connected to a 3.6V Zener (or maybe 3.3V on your specific board), this explains your result. Especially if you are using the USB feature at the same time. Conflict.

Once you moved to a free pin, you just need to wire it up correctly.

Pin 2 or 4 of the updated board schematic needs to be tied to ground. And then enable the input pull-up resistor, or add your own, from Pin 1 or Pin 3. The internal pull-up is typically 47k on most MCUs.

schematic

simulate this circuit – Schematic created using CircuitLab

Your pull-up forms the top part of a voltage divider. When no button is pressed, the ADC will read 1023 (5V). When SW1 is pressed, the line will be pulled to ground, and the ADC will read 0 (0V). When SW2 is pressed, the voltage divider will be 47k over 2.3k, and result in a voltage of 0.23V. At 5V / 1023 = 0.0048 V per ADC step, that's roughly a result of 47. When SW3 is pressed, the voltage divider will be 47k over 2.3k + 4.3k, voltage of 0.62V, and an ADC result of 127.

As @microtherion also pointed out, use ranges. An Analog result of 0 to 30 is SW1, 31 to 100 is SW2, 101 to 150 is SW3, etc. You could use a smaller value pull-up resistor to have some wider voltage ranges. 24kΩ or 10kΩ would work, just recalculate all the voltage ranges (or just hook it up and press the buttons to read them. You could also press multiple buttons at the same time for different values, except Still/Pause, which shorts the other buttons out.

\$\endgroup\$
6
  • \$\begingroup\$ You edit my question with this schematic. There are five pins on the board, no seven pins. Two of them are not in use. There are two groups. The red and the green like in the first schematic. I wrote that I can read the values, they are unique but very close. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 18:11
  • \$\begingroup\$ Forgot to mention that each button has it's own SMD resistor. So it is not like this schematic. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 18:17
  • \$\begingroup\$ This is definitely a DVD-1740, disasembled it myself, got the frontplate with DVD-1740 on it. It's weird that it is so different (reason: Made in China?). When I connect the board to PB2, it reads only 0. At PB3 I got 654 on idle (because of USB I think) and higher when press a button (like the values in my schematic). \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 19:10
  • \$\begingroup\$ Oh, i see, I am sorry for the inconvenience. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 19:15
  • \$\begingroup\$ Just added the right schematic to the question ;-) Didn't see this before. As you can see, it must be possible. \$\endgroup\$
    – Codebeat
    Jun 23, 2016 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.