Attiny85/Digispark Multiple Buttons

Hello. I am trying to use a Digispark with i2c led1602 and 3 buttons. Just for proof of concept I tried to use 2 buttons and the screen to display the state of the buttons. I do not know what I am doing wrong but I couldn't make it work. The screen goes crazy when I start the system.

Here is the code and below you can see the wiring

#include <TinyWireM.h>        
#include <LiquidCrystal_I2C.h> 

#define GPIO_ADDR     0x3f

LiquidCrystal_I2C lcd(GPIO_ADDR,16,2); 

const int button1 = 3;
const int button2 = 4;
const int ledPin =  1;
int button1State = 0;
int button2State = 0;

void setup(){
  pinMode(ledPin, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  
  TinyWireM.begin();
  lcd.init();
  lcd.backlight();
}

void loop(){
  delay(20);

  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  if(button1State==HIGH){
     digitalWrite(ledPin, HIGH);
     lcd.clear();
     lcd.print("1 is pressed");
  }
  else if(button2State==HIGH){
     digitalWrite(ledPin, HIGH);
     lcd.clear();
     lcd.print("2 is pressed");
     }
  else
    digitalWrite(ledPin, LOW);
    lcd.print("Press a button");
}

LED SDA - P0
LED SCL - P2
Button 1 - P3
Button 2 - P4

All the grounds same and the board is power from the pins not the USB. The system is on a breadboard with a breadboard power supply module. There are no resistors in the system.

What should I do?

The button switches need pull down resistors or else they will float to random states. Much better would be to connect the switches to ground and an input set to enable the internal pullup resistors with pinMode(pin, INPUT_PULLLUP); The pinMode() function reference.

You will need to adjust the program logic because the switches will read HIGH when not pressed and LOW when pressed.

I use the hd44780 library for my I2C LCDs. It is the best library available and it is actively maintained, unlike most of the LiquidCrystal libraries. To install the hd44780 library. The library is available in the Library Manager. Go to Library Manager (in the IDE menus, Sketch, Include Libraries, Manage Libraries) and in the Topics dropdown choose Display and in the Filter your search box enter hd44780. Select and install the hd44780 library by Bill Perry. The class that you want to use is the hd44780_I2Cexp class. There are examples to show how to use the library. The nice thing about the hd44780 library is that it will autodetect the I2C address and the I2C backpack to LCD pin mapping.

1 Like

I put 1k resistors between buttons and the pins. I fixed the LOW/HIGH confusion. After these changes the screen showed the "Press a button" text but nothing happened when I pressed the buttons neither on the screen nor the led. So I deleted the text on "else" case. Now the screen displays "2 is pressed" although I am not pressing. The led is on. But text changes to "1 is pressed" when I click the 1 button. The code is below

#include <TinyWireM.h>        
#include <LiquidCrystal_I2C.h> 

#define GPIO_ADDR     0x3f

LiquidCrystal_I2C lcd(GPIO_ADDR,16,2); 

const int button1 = 3;
const int button2 = 4;
const int ledPin =  1;
int button1State = 0;
int button2State = 0;

void setup(){
  pinMode(ledPin, OUTPUT);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  
  TinyWireM.begin();
  lcd.init();
  lcd.backlight();
  
}

void loop(){
  delay(50);

  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  
  if(button1State==LOW){
     digitalWrite(ledPin, HIGH);
     lcd.clear();
     lcd.print("1 is pressed");
  }
  else if(button2State==LOW){
     digitalWrite(ledPin, HIGH);
     lcd.clear();
     lcd.print("2 is pressed");
     }
  else
    digitalWrite(ledPin, LOW);
}

I was thinking that something is wrong about the screen and while digging the forum I found this post which is written by you exactly 2 years ago:) Troubles getting lcd display & i2c working with Digispark Attiny85

I already tried the library but got an error:

In file included from C:\Users....ino:2:0:
C:...\Arduino\libraries\hd44780/hd44780.h:152:77: error: '__FlashStringHelper' does not name a type
size_t attribute ((error("println() is not supported"))) println(const __FlashStringHelper *);
^
C:...\Arduino\libraries\hd44780/hd44780.h:152:97: error: ISO C++ forbids declaration of 'parameter' with no type [-fpermissive]
size_t attribute ((error("println() is not supported"))) println(const __FlashStringHelper *);
^
exit status 1
Error compiling for board Digispark (Default - 16.5mhz).

Post a schematic that shows how you wired the buttons. Your description does not sound right. What you need, if you won't change to active low (wired to ground) buttons, are pull down resistors. Those go from the switch input to ground and are much higher in value than 1K.

dig sw button pulldown

Post the code that generates the errors, please.

What core are you using for the tiny85. I like the ATTinyCore core. It is the best of all the cores for tiny85 that I tried and I think that I tried most of them.

1 Like

Sorry for the messy picture.

You are right, my connection was wrong. I fixed it like you said and changed the resistors with 10k ones. As you can see now screen displays "2 is pressed" all the time and button presses do not change anything but the led on the Digispark. Button 2 turns off the led on the board. Led is always on otherwise.

The code that gives the error is:

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip


// LCD geometry
const int LCD_COLS = 16;  // replace with your display parameters
const int LCD_ROWS = 2;

void setup()
{
   lcd.begin(LCD_COLS, LCD_ROWS);
   lcd.print("Hello, World!");
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 500;
   if (millis() - timer >= interval)
   {
      timer = millis();
      lcd.setCursor(0, 1);
      lcd.print("millis =        ");
      lcd.setCursor(8, 1);
      lcd.print(millis());
   }
}

I couldn't find any circuit design website that supports Digispark. Can you suggest me one? So I can give you a clearer picture of what I got.

Sorry, you also asked about the core.

I didn't know additional cores out there. I examined the link you gave. Downloaded the core and uploaded the code that gave error. It is working now.

However it worked when the board is connected via usb. It didn't work when board is powered via pins for the example I shared on previous post.

I tried to combine the lcd code you gave and the code I wrote previously. Now the core is what you gave but the problem is the same. I only see "2 is pressed". It works when the board is powered via pins btw.

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip


// LCD geometry
const int LCD_COLS = 16;  // replace with your display parameters
const int LCD_ROWS = 2;

const int button1 = 3;
const int button2 = 4;
const int ledPin =  1;
int button1State = 0;
int button2State = 0;

void setup()
{
   lcd.begin(LCD_COLS, LCD_ROWS);
   pinMode(ledPin, OUTPUT);
   pinMode(button1, INPUT_PULLUP);
   pinMode(button2, INPUT_PULLUP);
}

void loop(){
  delay(50);

  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  
  if(button1State==LOW){
     digitalWrite(ledPin, HIGH);
     lcd.clear();
     lcd.print("1 is pressed");
  }
  else if(button2State==LOW){
     digitalWrite(ledPin, HIGH);
     lcd.clear();
     lcd.print("2 is pressed");
     }
  else
    digitalWrite(ledPin, LOW);
}

It looks like your breadboard has the gap in the power rails (see yellow boxes). You need to jumper the gap to get power to the other side of the board (see black jumpers),

1 Like

Actually I am transferring the power with cables

If the pictures do not reflect reality they are not worth much.

OK I see. Sorry, I did not realize what you meant at first.

1 Like

Oh no worries. I am really new to these stuff. Sometimes even I do not understand what I say.

I tried to draw the schematics. I didn't wire the led to make things easy to read.

Is the code in reply #7 the latest and the code that you want to work on?

If so, wire the switches to ground like shown in reply #2 for the active low switches and internal pullups. That matches what you have in setup() (above). And it matches my attempt at duplicating your wiring.

That's right. I am using this wiring and code

And this is the board settings, if necessary:
image

I don't have a Digispark and have no experience with them.

I do see the pins 3 and 4 are connected to USB. Can you use those pins as GPIO? I don't know.

What is the final purpose of the project? Perhaps Digispark is not the best choice.

As far as I know these pins can be used if the board is not connect to usb.

Final purpose is to make a curing station for 3d resin prints. I have a uv led and a box but there is no timer. I want to use the Digispark with buttons, led and a relay to make a timer.

I also have a nano. Maybe I should use it instead. I just have more than 10 Digispark. That is why I wanted to use it. But it seems it is not going to work.

Thank you for your help man. I really appreciate it. I don't know how but I'd buy you a beer if I could:)

The Nano may be a better choice if not for any other reason than Nano is used by more members and help will be more forthcoming.

I did wire up a tiny85 on a breadboard with the I2C LCD, 2 push switches and an LED. I slightly modified your code and uploaded to my tiny85. The switches are wired to ground and using the internal pullups. When no buttons are pressed the LCD reads "none pressed". Press button1 and the LCD reads "1 is pressed" and the LED lights as long as the button is pressed. Reverts to "none pressed" when the button is released. Press button 2 and the LCD reads "2 is pressed" and the LED lights as long as the button is pressed. On release the LCD reads "none pressed". If the code does not work and the wiring is the same between my setup and yours, I would say that the Digispark, being the difference, is the culprit.

The modified code:

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip


// LCD geometry
const int LCD_COLS = 16;  // replace with your display parameters
const int LCD_ROWS = 2;

const int button1 = 3;
const int button2 = 4;
const int ledPin =  1;
int button1State = 0;
int button2State = 0;

void setup()
{
   lcd.begin(LCD_COLS, LCD_ROWS);
   pinMode(ledPin, OUTPUT);
   pinMode(button1, INPUT_PULLUP);
   pinMode(button2, INPUT_PULLUP);
}

void loop()
{
   delay(50);

   button1State = digitalRead(button1);
   button2State = digitalRead(button2);

   if (button1State == LOW)
   {
      digitalWrite(ledPin, HIGH);
      lcd.clear();
      lcd.print("1 is pressed");
   }
   else if (button2State == LOW)
   {
      digitalWrite(ledPin, HIGH);
      lcd.clear();
      lcd.print("2 is pressed");
   }
   else
   {
      digitalWrite(ledPin, LOW);
      lcd.clear();
      lcd.print(" none pressed");
   }
}

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.