Problem with simple analog in/LCD display on MH-Tiny ATtiny88 Board

Hi All -

I am a relative newbie to the Arduino IDE, but I had this code running on an ATtiny85. I just wanted to add a few more analog ins. I thought it would be a straight forward port. The code compiles and uploads. When I connect the MH-Tiny ATtiny88 to the LCD and supply power, 'Voltage:' and 'Flow' are displayed on the LCD, but the values from the analogread are not displayed.

The code is below.


#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows


void setup() {
  // put your setup code here, to run once:
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Voltage:");
  lcd.setCursor(0, 1);
  lcd.print("Flow:");
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
 
  // read the input on analog A2:
  int sensorValue = analogRead(2);
  float voltage = float(sensorValue)*(5.0/1023.0);
  
  // read the input on analog A0:
  sensorValue = analogRead(0);
  float flowRate = float(sensorValue)*(5.0/1023.0);

  // print out the values you read:
  lcd.setCursor(12, 0);
  lcd.print(String(voltage,2));
  lcd.setCursor(12, 1);
  lcd.print(String(flowRate,2));
}

Again, this works when uploaded to an ATtiny85, but it seems to hang in the Loop function. It is almost like it doesn't enterthe loop.

Thanks for any help,

You need to check up the ATtiny 85 and 88 and compare. Something is different from one to the other.
What made You think they are compatible?
How is the wiring made? Using breadboards?

As far as I can tell, the ATtiny 85 and 88 are pretty compatible similar. I did change the pinouts numbers to match the 88.

Also, I do change the board from ATtiny 85 to ATtiny 88.

The LCD does display ‘Voltage:’ and ‘Flow:’, but no values. I removed all the circuitry except the LCD connected to the SDA and SLC pins, so the analog in should read just the default value.

I am able to run the blink example sketch on the 88.

Pretty compatible might not be good enough. Board pins would be unsafe to compare. Is the core controller chip the same? Different chips often differs regarding timers etc.

No, the core chip is not the same. The core chip on the ATtiny85 board is the ATtiny85 chip and the corechip on the MH-Tiny ATTINY88 Micro Development Board 16Mhz is the ATtiny88.

ATtiny pinout
MH Tiny ATtiny pinout

I’m using the ATTinyCore and I’ve included the correct ‘Wires’ and the ‘LiquidCrystal_i2C’ libraries. I am compiling for the appropriate board.

Also, the LCD power is coming directly from a regulated power supply instead of the board. I think it was drawing too much current for the ATtiny85 board.

Maybe I’m looking in the wrong place. Since the LCD is being displayed, initially, but it doesn’t seem like the Loop is actually being entered. Maybe the problem is with the LCD board connection.

Print out a message in the very top of loop. When confirmed, move that pritout down.

We were thinking alike. I moved the lcd.print commands to the Loop and can see the 'Voltage:' and 'Flow:', but no values. I then commented out the lcd.print(voltage), and lcd.print(flow) lines and added lcd.print("HI") and lcd.print("BYE"). They appeared. Then, I commented them out the test lines and casting the sensorValues to a float and printed out the sensorValue. I now see an integerValues. I connected the center out of potentiometers to the A0 and A2 pins and I can see the integerValues change. It appears the problem is with the casting to a float. Any recommendations?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows


void setup() {
  // put your setup code here, to run once:
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  
}

void loop() {
  // put your main code here, to run repeatedly:
 
  // read the input on analog A2:
  lcd.setCursor(0, 0);
  lcd.print("Voltage:");
  int sensorValue = analogRead(2);
//  float voltage = float(sensorValue)*(5.0/1023.0);
  // print out the value you read:
  lcd.setCursor(12, 0);
  lcd.print(String(sensorValue));
//  lcd.print(String(voltage,2));
//  lcd.print("HI");
  
  // read the input on analog A0:
  lcd.setCursor(0, 1);
  lcd.print("Flow:");
  sensorValue = analogRead(0);
  float flowRate = float(sensorValue)*(5.0/1023.0);
  // print out the value you read:
  lcd.setCursor(12, 1);
  lcd.print(String(sensorValue));
//  lcd.print(String(flowRate,2));
//  lcd.print("BYE");
}

A step forward. Drop the conversion using string. lcd.print does that.Make sure there is place for the characters of the printed value. Locating to position 12 there are only 4 positions left. There's no wrap around in those lcd's. Rather, strange things happen.

A follow up - I created a test variable floatValue and then tried printing the value. The a blank appears. When I try separate the casting and printing, the code will not compile.

It appears that String is not a defined type.

  float floatValue = 0.0;
  String stringValue = String(floatValue,2);

String is not recognized. When I try to include the 'stdlib' or 'string', I receive a Sketch too big error when compiling.

OK, I'm started to look at how much memory the sketch uses. On the ATtiny85 it uses 94% of the program storage space and on the MH-Tiny it uses ~104% of the memory space. My question is can I trim some of the 'LiquidCrystal_I2C' library, since I am only using a few functions. If so, can you point me to any resources?

Thanks,

As far as I can tell, the these are the data type for lcd.print

data: the data to print (char, byte, int, long, or string)

from

So much for reading manuals. It seems to work. Thank you.

Okey. I use another library and it prints floats. Main thing is You got things working.

At home.
Here's a code using another I2C LCD library printing floats. The library is hd44780.h. Note the second #include line.

Search for "accFloatAngle".

Code:

#include<arduino.h>

//I2C for LCD
#include <AccelStepper.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>

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

AccelStepper myStepper (1, 6, 7);

// LCD geometry
#define LCD_COLS 16
#define LCD_ROWS 2

enum mode {Sides, Angle };
mode Mode; //Angle or Step mode
unsigned long nrOfFaces = 4;//Will be prompted in Setup
float stepAngle = 90.0;// will be set when angles selected
unsigned long nrOfStepsPerRev = 200L * 32L * 90L; // microstep 16
unsigned long currentStep;
unsigned long anglePos;
float accFloatAngle;//for display only

enum cmd {increase, decrease, Go, ChgMode, GoStep, nobutton};

void setup() {
  char inChar;
  Serial.begin(115200);
  Serial.println("Rotation ");

  pinMode(13, OUTPUT); digitalWrite(13, LOW);// Make board LED go off

  myStepper.setMaxSpeed(4000);
  myStepper.setAcceleration(30000);

#define digitalIncreaseButton 2
  pinMode (digitalIncreaseButton, INPUT_PULLUP);

#define cuttingSpeed 100 // when cutting during rotation
#define movingSpeed 500 //when moving without cutting


  int status;
  status = mylcd.begin(LCD_COLS, LCD_ROWS);
  if (status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
    hd44780::fatalError(status); // does not return
  }
  mylcd.clear();

  mylcd.print("230227a Rotating");
  mylcd.setCursor(0 , 1);
  mylcd.print("Step Angle Chang");

  Serial.println("230227a Rotating. S: Steps, A:Angle");

  while (!Serial.available()) {}; //Wait for Serial input

  inChar = Serial.read();//Read type of mode, Sides or Angle

  if (inChar == 's')inChar = 'S';//  DOESN*T work
  if (inChar == 'S')//ORIGINAL S works
  {
    Serial.println("Step mode selected");

    mylcd.clear();//command sent, here we go.
    mylcd.setCursor(0 , 0);
    mylcd.print("Step Mode       ");

    Mode = Sides;
    while (!Serial.available()) {}; //Wait for Serial input
    nrOfFaces = ParseLong();
    if (nrOfFaces > nrOfStepsPerRev)nrOfFaces = nrOfStepsPerRev;//Not above max
    //    nrOfFaces = Serial.parseInt();
    Serial.print("Sides/Faces = "); Serial.println(nrOfFaces);

    mylcd.setCursor(0 , 1);
    mylcd.print("Step            ");
    mylcd.setCursor(5 , 1);
    mylcd.print(nrOfFaces);
  }


  if (inChar == 'a')inChar = 'A';
  if (inChar == 'A')
  {
    Serial.println("Angle mode selected");

    mylcd.clear();//command sent, here we go.
    mylcd.setCursor(0 , 0);
    mylcd.print("Angle Mode      ");

    Mode = Angle;
    while (!Serial.available()) {}; //Wait for Serial input
    stepAngle = Serial.parseFloat();
    if (stepAngle < 0) stepAngle = 0;
    Serial.print("Angle step = "); Serial.println(stepAngle);

    mylcd.setCursor(0 , 1);
    mylcd.print("Angle           ");
    mylcd.setCursor(6 , 1);
    mylcd.print(stepAngle);

  }
  myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
  anglePos = 0;
  currentStep = 0;
  Serial.println("S for stepping, both step/faces and angle");
  //  delay(5000);
}

enum cmd readButtons(void)
{
  char cmd = 'q';

  if (digitalRead(digitalIncreaseButton) == 0)
  {
    Serial.println("Button step received");
    Serial.println();
    delay(300); //debouncing
    Serial.print("Recieved b cmd "); Serial.println(cmd);
    return (GoStep);
  }//     increase);
  if (Serial.available() > 0)
  {
    cmd = Serial.read();
  }

  if (cmd == 's' )
  {
    Serial.print("Recieved s cmd "); Serial.println(cmd);
    return (GoStep);
  }
  if (cmd == 'S' ) {
    Serial.print("Recieved S cmd "); Serial.println(cmd);
    return (GoStep);
  }

  if (cmd == 'c' )
  {
    Serial.print("Recieved c cmd "); Serial.println(cmd);
    return (ChgMode);
  }
  if (cmd == 'C' ) {
    Serial.print("Recieved C cmd "); Serial.println(cmd);
    return (ChgMode);
  }

  return (nobutton);
}

unsigned long ParseLong(void)
{
  boolean goFlag = true;//read, decode and add digits
  char tmpChar;
  unsigned long longSum = 0;
  while (!Serial.available()) {};
  while ( Serial.available() && goFlag )
  {
    tmpChar = Serial.read();
    if (isDigit(tmpChar))  // a numerical character recieved?
    {
      longSum *= 10l;// x 10
      Serial.print( "Tmp char conversion "); Serial.println(tmpChar - '0');
      longSum += tmpChar - '0';// + new digit
      Serial.print( "longSum = "); Serial.println(longSum);
    }
    else
      goFlag = false; //none digit entry

    //    Serial.print( "ParseLong = "); Serial.println(longSum);
  }
  return (longSum);
}

boolean guardCheck(void)
{
  /* commented out until hardware is designed
    if (!digitalRead(guard1) && !digitalRead(guard2))
    return (true);//Unlocked, clear to go
    else
    return false;//Locked, don't go
  */
  return (true);
}

void loop()
{
  unsigned long lastMillis;
  //  unsigned long anglePos;
  enum cmd lcmd;
  //  enum mode lmode;
  //  float accFloatAngle;//for display only
  float tmpfloat;
  char dummyChar;

  lcmd = readButtons();// Read button inputs/ Serial, if any    + - Go Chg mode

  while (Serial.available() > 0) dummyChar = Serial.read(); // Multiple cmd flushed.

         if ( millis() - lastMillis > 200 )
  {
    lastMillis = millis();
      if ( Mode == Sides )  //number of surnrOfFaces
      {
        switch (lcmd)
        {
          case increase:
            {
              nrOfFaces++;
              break;
            }
          case decrease:
            {
              nrOfFaces--;
              if (nrOfFaces < 2)
              {
                nrOfFaces = 1; //1 rotate one turn
                //              myStepper.setMaxSpeed(cuttingSpeed);
              }
              else
                //              myStepper.setMaxSpeed(movingSpeed);
                break;
            }
          case ChgMode:
            {
              myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
              anglePos = 0;
              currentStep = 0;
              accFloatAngle = 0;

              setup();// Ask for new mode
              break;
            }
          case Go:
            {
              while (!guardCheck());;//DON*T GO IF LOCKS ARE ON
              anglePos += nrOfStepsPerRev / nrOfFaces;
              //            myStepper.runToNewPosition();//Blocking until done
              break;
            }

          case GoStep:
            {
              Serial.println("GoStep S received. ");
              while (!guardCheck());;//DON*T GO IF LOCKS ARE ON

              mylcd.setCursor(0 , 1);
              mylcd.print("                ");
              mylcd.setCursor(0 , 1);//Ready for start step
              mylcd.print(currentStep);
              mylcd.print(" > ");

              Serial.print("From face "); Serial.print(currentStep);
              Serial.print(" steps "); Serial.print( anglePos);
              tmpfloat = (360.00 * currentStep) / nrOfFaces;
              Serial.print(" angle = "); Serial.print( tmpfloat );

              anglePos = (nrOfStepsPerRev * ++currentStep) / nrOfFaces;
              currentStep %= nrOfFaces;

              Serial.print(" To face "); Serial.print(currentStep);
              Serial.print(" steps "); Serial.print( anglePos);
              tmpfloat = 360.0 * float(currentStep) / float(nrOfFaces);
              Serial.print(" angle = "); Serial.println( tmpfloat);

              mylcd.print(currentStep);

              lastMillis = millis();
              myStepper.runToNewPosition(anglePos);//Blocking until done

              Serial.print("Runtime "); Serial.println( millis() - lastMillis);
              Serial.println("Ready."); Serial.println();

              if (currentStep == 0)// Back on zero position, update AccelStepper position!!!
                myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
              break;
            }
          default:
            break;
        }//end of switch
      }//end of "if (lmode == Sides)"
      else if ( Mode == Angle )  // Angle per step
      {
        switch (lcmd)
        {
          case increase:
            {
              anglePos = nrOfStepsPerRev * ++currentStep / nrOfFaces;
              break;
            }
          case decrease:
            {
              anglePos = nrOfStepsPerRev * ++currentStep / nrOfFaces;
              if (nrOfFaces < 1) nrOfFaces = 1; //1 rotate one turn
              break;
            }
          case ChgMode:
            {
              myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
              anglePos = 0;
              currentStep = 0;
              accFloatAngle = 0;

              setup();// Ask for new mode
              break;
            }
          case GoStep:
            {
              while (!guardCheck());;//DON*T GO IF LOCKS ARE ON

              if (accFloatAngle >= 360.0)accFloatAngle -= 360.0;
              if (anglePos >= nrOfStepsPerRev)anglePos -= nrOfStepsPerRev;

              Serial.print("From steps "); Serial.print( anglePos);
              Serial.print(" angle "); Serial.print( accFloatAngle );

              mylcd.setCursor(0 , 1);
              mylcd.print("                ");
              mylcd.setCursor(0 , 1);//Ready for start step
              mylcd.print(accFloatAngle);//current F-angle
              mylcd.print(" > ");

              accFloatAngle += stepAngle;                           // Float angle to go to.
              anglePos = accFloatAngle * nrOfStepsPerRev / 360.0 ; // Angle in steps

              if (accFloatAngle >= 360.0)mylcd.print(accFloatAngle - 360.0);
              else mylcd.print(accFloatAngle);

              Serial.print(" To step  ");
              Serial.print( anglePos);

              Serial.print(" angle "); Serial.println(accFloatAngle);
              Serial.print("anglePos sent to accelstepper: "); Serial.println(anglePos);
              lastMillis = millis();
              myStepper.runToNewPosition(anglePos);//Blocking until done
              Serial.print("Runtime "); Serial.println( millis() - lastMillis);


              if (anglePos >= nrOfStepsPerRev )
              {
                myStepper.setCurrentPosition(anglePos - nrOfStepsPerRev);//Accelstepper ready for a second turn around
                Serial.print("setCurrentPosition to "); Serial.println(anglePos - nrOfStepsPerRev);
              }
              anglePos = accFloatAngle * nrOfStepsPerRev / 360.0 ; // in steps

            }
          default:
            break;
        }
      }
    }
  //  if (guardCheck())
  //  {
  //    Serial.print("!");
  //myStepper.run();
  //  }
}// End of loop

Thanks again. I’ll check out the HD44780 LCD library and see if it is smaller.

Is size critical? The good about this library is that it finds the address of the lcd.

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