Hi!
I have a huge Interrupt problem with Attiny85, an OLED display SD1306 (4 pins: GND, VCC, SDA, SCL), and the COJOE RadiationD-v1.1 Geiger counter. With the code for Arduino NANO/UNO, everything works using the following code:
//ARDUINO NANO
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define integratingTime 1000 //Logging period in milliseconds
unsigned long cps = 0; //variable for GM Tube events
unsigned long counts = 0; //variable for CPM
unsigned long previousMillis; //variable for time measurement
#define OLED_RESET 4
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16 // do not change this. Error in video
#define LOGO16_GLCD_WIDTH 16 // do not change this. Error in video
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000 };
#if (SSD1306_LCDHEIGHT != 64)
#endif
void tube_impulse() //subprocedure for capturing events from GM board
{
counts++;
}
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
attachInterrupt(digitalPinToInterrupt(2), tube_impulse, FALLING);
display.clearDisplay();
outDisplay("CPS: ",cps, 0, 32, 2);
display.display();
}
void loop(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > integratingTime){
previousMillis = currentMillis;
cps=counts;
counts = 0;
}
display.clearDisplay();
outDisplay("CPS: ",cps, 0, 20, 2);
display.display();
}
void outDisplay(String text,long cps, int x, int y,float size) {
display.setTextColor(WHITE);
display.setCursor(x,y);
display.setTextSize(size);
display.print(text+cps);
}
The interrupt here works with the "attachInterrupt(...)" function on pin D2 (INT0) (while with pin D3, INT1 doesn't work). I need to simplify everything for the Attiny85, avoiding the unnecessary use of an Arduino NANO. The Attiny85 has predefined pins for SCL (pin 7) and SDA (pin 5) for the display, but the same INT0 interrupt of Arduino NANO/UNO on pin D2 is pin 7 (already used by the OLED display for SCL).
The following code is one of the many attempts to achieve the same interrupt but with a different pin than pin 7 (INT0):
//Attiny85
#include "Wire.h"
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
#define integratingTime 1000 //Logging period in milliseconds
unsigned long cps = 0; //variable for GM Tube events
unsigned long counts = 0;
unsigned long totcounts = 0;
unsigned long previousMillis; //variable for time measurement
const int INTERRUPT_PIN = 1;
ISR(PCINT0_vect) {
counts++;
totcounts++;
}
void setup(){
pinMode(INTERRUPT_PIN, INPUT_PULLUP);
cli();
PCMSK |= (1 << digitalPinToPCMSKbit(INTERRUPT_PIN)); // Pin Change Enable
GIMSK |= (1 << digitalPinToPCICRbit(INTERRUPT_PIN)); // PCIE Pin Change Interrupt Enable
// equivalent to: GIMSK |= (1 << PCIE);
sei();
Wire.begin();
Wire.setClock(33000L);
#if RST_PIN >= 0
oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
oled.setFont(Adafruit5x7);
oled.set2X();
}
void loop(){
oled.set2X();
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > integratingTime){
previousMillis = currentMillis;
cps=counts;
counts = 0;
}
oled.home();
oled.println();
oled.print("CPS: "); oled.print(cps); oled.print(" ");
oled.println();
oled.set1X();
oled.println();
oled.println();
oled.println();
oled.print("ToT: "); oled.print(totcounts);
}
Please ignore the part about the display because it works fine. If there are any possible solutions, they are:
- Take the interrupt, as in the previous attempt, from a different pin other than pin 7 and pin 5.
- Take the interrupt from pin 7 (INT0) and use pin 5 as SDA for the display, and another pin for SCL (in this case, I would need to use different libraries, but I'm not sure how to do it).
The code should be able to receive the signal from the Geiger counter and increment a variable. I have used different libraries for Arduino (which don't work well for Attiny85).
Can anyone provide me with some solutions? It's URGENT XD