How to convert - Uno -> ATtiny85

I changed as you suggested (removed void) and did no other changes:

Now I am getting really a number of errors - I am afraid the worning from DrAzzy is what comes now:

Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "ATtiny25/45/85, ATtiny85, Internal 8 MHz"

In file included from C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/SSD1306AsciiAvrI2c.h:26:0,

                 from C:\Users\Frede\Dropbox\ALL  -  P R O J  E C T S\Grammofon-IR-Tacko\Project-2019-11-V0.2-RPM-OLED-ATtiny85\Project-2019-11-V0.2-RPM-OLED-ATtiny85.ino:2:

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'void AvrI2c::begin(bool)':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:65:5: error: 'TWSR' was not declared in this scope

     TWSR = 0;

     ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:65:5: note: suggested alternative: 'ACSR'

     TWSR = 0;

     ^~~~

     ACSR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'uint8_t AvrI2c::read(bool)':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:77:19: error: 'TWINT' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));

                   ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:77:34: error: 'TWEN' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));

                                  ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:77:34: note: suggested alternative: 'ADEN'

     execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));

                                  ^~~~

                                  ADEN

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:77:60: error: 'TWEA' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));

                                                            ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:78:12: error: 'TWDR' was not declared in this scope

     return TWDR;

            ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:78:12: note: suggested alternative: 'DWDR'

     return TWDR;

            ^~~~

            DWDR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'void AvrI2c::setClock(uint32_t)':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:98:5: error: 'TWBR' was not declared in this scope

     TWBR = ((F_CPU / frequency) - 16) / 2;

     ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:98:5: note: suggested alternative: 'TIFR'

     TWBR = ((F_CPU / frequency) - 16) / 2;

     ^~~~

     TIFR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'bool AvrI2c::start(uint8_t)':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:109:19: error: 'TWINT' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));

                   ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:109:34: error: 'TWSTA' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));

                                  ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:109:34: note: suggested alternative: 'TWSR_START'

     execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));

                                  ^~~~~

                                  TWSR_START

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:109:49: error: 'TWEN' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));

                                                 ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:109:49: note: suggested alternative: 'ADEN'

     execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));

                                                 ^~~~

                                                 ADEN

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:114:5: error: 'TWDR' was not declared in this scope

     TWDR = addressRW;

     ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:114:5: note: suggested alternative: 'DWDR'

     TWDR = addressRW;

     ^~~~

     DWDR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'void AvrI2c::stop()':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:126:5: error: 'TWCR' was not declared in this scope

     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

     ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:126:5: note: suggested alternative: 'EECR'

     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

     ^~~~

     EECR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:126:18: error: 'TWINT' was not declared in this scope

     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

                  ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:126:33: error: 'TWEN' was not declared in this scope

     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

                                 ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:126:33: note: suggested alternative: 'ADEN'

     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

                                 ^~~~

                                 ADEN

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:126:47: error: 'TWSTO' was not declared in this scope

     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

                                               ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'bool AvrI2c::write(uint8_t)':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:139:5: error: 'TWDR' was not declared in this scope

     TWDR = data;

     ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:139:5: note: suggested alternative: 'DWDR'

     TWDR = data;

     ^~~~

     DWDR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:140:19: error: 'TWINT' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWEN));

                   ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:140:34: error: 'TWEN' was not declared in this scope

     execCmd((1 << TWINT) | (1 << TWEN));

                                  ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:140:34: note: suggested alternative: 'ADEN'

     execCmd((1 << TWINT) | (1 << TWEN));

                                  ^~~~

                                  ADEN

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h: In member function 'void AvrI2c::execCmd(uint8_t)':

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:149:5: error: 'TWCR' was not declared in this scope

     TWCR = cmdReg;

     ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:149:5: note: suggested alternative: 'EECR'

     TWCR = cmdReg;

     ^~~~

     EECR

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:151:27: error: 'TWINT' was not declared in this scope

     while (!(TWCR & (1 << TWINT))) {}

                           ^~~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:153:15: error: 'TWSR' was not declared in this scope

     status_ = TWSR & 0xF8;

               ^~~~

C:\Users\Frede\Documents\Arduino\libraries\SSD1306Ascii\src/utility/AvrI2c.h:153:15: note: suggested alternative: 'ACSR'

     status_ = TWSR & 0xF8;

               ^~~~

               ACSR

exit status 1
Error compiling for board ATtiny25/45/85.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

My edit of post #19 crossed with your reply.

But, anyway, my suggestion is that you now revert to a previous project, any project, where you have had the OLED screen working with the ATTiny85. Just get to the stage of printing "Hello World" on the screen from the ATTiny85 then post that code here. I (or someone else) will then give you a hand combining that with your gramophone speed check code.

6v6gt
I actually replyed to earlier codes working in post#16.

I will follow your (and DrAzzy) advice and start all over again.

Thank you very much for your help - I will use you input building the application / code.
I did learn much more by the help here.

As a milestone for now, here is the full code working on Arduino UNO (if someone are interested).

/* --- Gramophone speed measuring -------------------------------------------------------------
 * Parts:
 * Controller: Arduino UNO  
 * Display: OLED 128x32
 * Sensor: Infrared 
 * --------------------------------------------------------------------------------------------
 * THIS SKETCH is running on Arduino UNO
 * Target is to change for ATTINY 85 later
 * --------------------------------------------------------------------------------------------
 * UNO Resources:   7303b - 22% /  110b / 5%   --- Updated: 2019-11-22
 **********************************************************************************/   
  #include "SSD1306Ascii.h"                          
  #include "SSD1306AsciiAvrI2c.h"           
  #define I2C_ADDRESS 0x3C                     
  SSD1306AsciiAvrI2c OLED;
//*********************************** varable definitions ******************************
  #define intrp_pin 3
  unsigned long abort_time;
  float rpm ;
  volatile byte intp_flag = 0 ;  
  volatile unsigned long start_time = 0 ;   //start platen index pulse time value
  volatile unsigned long end_time   = 0 ;   //end platen index time value
//*********************************************************************************
void setup(){
  // --- Display setup --------------------------------------------------------------
  OLED.begin(&Adafruit128x32, I2C_ADDRESS);
  OLED.clear();
  // --- Sensor setup ---------------------------------------------------------------  
  pinMode(intrp_pin, INPUT_PULLUP); 
  attachInterrupt(digitalPinToInterrupt(intrp_pin), index_pulse_time, FALLING);
  // --- Start text -----------------------------------------------------------------
  vis();
}
//*********************************************************************************
void loop(){
  rpm_calc() ;                                //rpm function calculation
  disp_msg() ;                                //display function
  unsigned long waitMillis= millis(); 
  while(millis() - waitMillis < 1000);
}
//*************************** rpm calculation  ****************************************
void rpm_calc(){
  float calc_time = 0;
  signal_check() ;   
  calc_time = (end_time - start_time) / 1000000.0;
  rpm = ( 1.0 / calc_time) * 60.0 ;
}
//******************************* check signal is present ******************************
void signal_check(){
  intp_flag = 0;abort_time = millis();
  do{if(millis() - abort_time > 5000){pwr_off_msg();}
  }while(intp_flag <= 2);
}
//*********************************display rpm function *******************************
void disp_msg(){
   OLED.clear();
   OLED.setFont(ZevvPeep8x16);OLED.setCursor(0,2);OLED.print("RPM: ");
   OLED.setCursor(40,0);OLED.setFont(fixednums15x31);OLED.print(rpm,2);
}
//*****************************no switch Power OFFF message ***************************
void pwr_off_msg(){
  OLED.setFont(ZevvPeep8x16);OLED.clear();                                             
  do{OLED.setCursor(30,2);OLED.print("POWER OFF");
  unsigned long waitMillis= millis(); while(millis() - waitMillis < 500);
  }while(digitalRead(intrp_pin) != 1);
}
//*********************************************************************************
void index_pulse_time(){
  switch(intp_flag){
    case 0:break;
    case 1:start_time = micros();break;
    case 2:end_time = micros();
  }
  intp_flag = intp_flag + 1;
}
//******************************** read time function *********************************
void index_pulse_time2(){
  if(intp_flag == 1){start_time = micros();}   //read index start time
  if(intp_flag == 2){end_time = micros();}     //read index end time
  intp_flag = intp_flag + 1 ;
}
//*********************************************************************************
void vis(){
  OLED.setFont(ZevvPeep8x16);OLED.clear();
  OLED.setCursor(0,0);OLED.print("Thorens TD124-II"); 
  unsigned long waitMillis = millis(); 
  while (millis() - waitMillis < 3000); 
}
//*********************************************************************************

What you need to find is an attiny compatible OLED display library.

Personally, I hate those OLED displays - I don't know if you've noticed yet, but they're not exactly well-made; the displays themselves are meant to be used in cases where there's a housing with a hole sized for the screen, which will protect the screen from damage during handling. Of course, we normally don't have the luxury of a custom case of precisely the right shape for our projects. So the screens are very fragile. I have had brand new OLED screens (IIRC it was the 128x32 one) fall apart in my hands. They are also so tiny that nobody older than their 40's can read text on the screens.

I instead use the 1602 and 2004 HD44780 character LCDs most of the time (you can also get 4002 and 4004 size if you need a ginormous character LCD) - the screens are nice and big so they're easy to read, are dirt cheap, and being a character LCD instead of a graphical one, you don't need to worry about the display buffer. You can get them with the I2C backpack, and the LiquidCrystal_I2C library uses Wire.h for I2C functionality so if using my core, the library will work out of the box with an ATTiny that has a USI instead of a full TWI interface.

DrAzzy,

Interesting view regarding displays :slight_smile: .

Of experience - i know you are right. The small OLED are fragile.

I am using these displays for many reasons. Mostly because of the size and I have worked out at certain experience handling the displays.
Your point custom case ect. - yes correct. I am so lucky to have a good friend who owns a 3D printer and he is making black frames for the displays.
Also design ALU front panels for my designs. The front panels combined with the black frames - a nice solution.


The current project.

I am working on this design for a classic Thorens TD 124 turntable.
My target is to be able to build the hardware so it can be build in the Thorens without any mechanical changes. I expect to replace a 50Hz lamp for the strobe with the ATtiny85 and OLED 128x32 display.

And for the Arduino coding.
I see light ahead.

I have found this OLED library: Tiny4kOLED

And I have the function working with interrupt on pin PB1 on the ATtiny85.

I will of course post the code here when it is ready.

And again - all your help here made it possible for me get this solution working. Thank you


The attachedment: the OLED 128x32 display with a big font. :slight_smile:

display.JPG

I have now the working sketch for Arduino ATtiny85.

If anyone is interested - I will of coarse have an Eagle board for the project.

This is the ATtiny85 code:

/* Project name: Gramophone speed measuring -------------------------------------
 * Version: Project-2019-11-V1.3
 * Parts:
 * ATTiny85 (8 MHz) 
 * x-tal 8 MHz
 * OLED (I2C) 128x32
 * IR sensor - Tcrt5000 Sensor
 * ------------------------------------------------------------------------------- 
 * Resources: ATtiny85;  7574b / 92% - 137b / 26%
 ********************************************************************************/
  #include <Tiny4kOLED.h>
  // --- interrupt definitions --------------------------------------------------
  #define INTERRUPT_PIN PCINT1               // This is PB1 per the schematic
  #define intrpPin PB1                       // Interrupt pin: PCINT1/PB1/pin 6
  #define PCINT_VECTOR PCINT0_vect           
  //--- variables defined -------------------------------------------------------
  float rpm;
  volatile byte intrpCase = 0;
  unsigned long stopTime = 0;    
  volatile unsigned long startTime = 0;     //start platen index pulse time value
  volatile unsigned long endTime   = 0;     //end platen index time value
  //--- average variables -------------------------------------------------------
  int x = 0;boolean avgCalc = false;
  float rpmAvg, avg[10];  
// ****************************************************************************** 
void setup(){
  // --- Display setup ----------------------------------------------------------
  oled.begin();
  oled.clear();oled.on();
  oled.switchRenderFrame();
  // --- Sensor setup -----------------------------------------------------------  
  cli();                            // Disable interrupts during setup
  PCMSK |= (1 << INTERRUPT_PIN);    // Enable (ISR) for pin (PCINT1/PB1/pin 6)
  GIMSK |= (1 << PCIE);             // Enable PCINT interrupt
  pinMode(intrpPin, INPUT_PULLUP);   
  sei();                            //Enable interrupts after setup
  // --- Display start text -----------------------------------------------------
  vis();
}
// ******************************************************************************
void loop(){
  rpmCalc();                              
  disp_msg();
  // --- update delay -------------------                                
  unsigned long waitMillis= millis(); 
  while(millis() - waitMillis < 1000);
}
//*************************** rpm calculation  **********************************
void rpmCalc(){
  float calcTime = 0;signalCheck();   
  calcTime = (endTime - startTime) / 1000000.0;
  rpm = (1.0 / calcTime) * 60.0;

  // --- calculate average value -----------------------
  avg[x] = rpm;
  if(x < 10){x++;}
  else{x = 0;avgCalc = true;}
  
  if(avgCalc == true){
  for(int i = 0;i < 10;i++){rpmAvg += avg[i];}
  rpm = rpmAvg / 10;rpmAvg = 0;
  }  
}
//*******************************************************************************
ISR(PCINT_VECTOR){
  switch(intrpCase){
    case 0:break;
    case 1:startTime = micros();break;
    case 2:endTime = micros();
  }
  if(intrpCase == 1){startTime = micros();}
  if(intrpCase == 2){endTime = micros();}    
  intrpCase = intrpCase + 1 ;
}
//*********************************display rpm function *************************
void disp_msg(){
   oled.clear();oled.setFont(FONT16X32);oled.setCursor(30,2);
   oled.print(rpm,2);oled.switchFrame();
}
// ******************************************************************************
void signalCheck(){
  intrpCase = 0;stopTime = millis();
  do{if(millis() - stopTime > 5000){pwrOFF();}
  }while(intrpCase <= 2);
}
//*****************************no switch Power OFFF message *********************
void pwrOFF(){
  oled.setFont(FONT8X16);oled.clear();                                             
  do{oled.setCursor(30,2);oled.print("POWER OFF");oled.switchFrame();
  unsigned long waitMillis= millis(); while(millis() - waitMillis < 500);
  }while(digitalRead(intrpPin) != 1);
}
//*******************************************************************************
void vis(){
  oled.clear();oled.setFont(FONT8X16);oled.setCursor(0, 0);
  oled.print(F("Thorens TD124-II"));oled.switchFrame();
  unsigned long waitMillis= millis(); 
  while(millis() - waitMillis < 3000); 
}
//*************************** E N D  ********************************************

Cool; you should put the sketch and eagle design files into a github repo if you want to share it with the world - that's how people share open source software these days.