This code works perfectly on my Arduino Uno, using Pin A0 for the signal input and Digital Pin 1 for the LED. However, after burning the code to my ATtiny84, the LED stays on constantly, regardless of the signal present at the signal pin—it remains high at all times. Is this code not compatible with the ATtiny84?
const int signalPin = 2; // The analog pin reading the DC signal
const int ledPin = 1; // The digital pin controlling the LED
const int threshold = 11; // -23 dBu
const unsigned long holdTime = 2000; // Time in milliseconds to hold LED on
unsigned long ledTurnOnTime = 0; // To track when the LED was turned on
bool ledOn = false; // To track the LED state
// Define unused pins
const int ncPin2 = 0; // Not connected
const int ncPin3 = 3; // Not connected
const int ncPin4 = 4; // Not connected
void setup() {
pinMode(ledPin, OUTPUT); // Set LED pin as an output
pinMode(signalPin, INPUT); // Set signal pin as input
// Set unused pins to input pull-up mode
pinMode(ncPin2, INPUT_PULLUP);
pinMode(ncPin3, INPUT_PULLUP);
pinMode(ncPin4, INPUT_PULLUP);
}
void loop() {
int signalValue = analogRead(signalPin); // Read the analog signal
// If signal is above threshold, turn on LED and record the time
if (signalValue >= threshold) {
digitalWrite(ledPin, HIGH); // Turn on the LED
ledTurnOnTime = millis(); // Record the time the LED was turned on
ledOn = true; // Set flag to indicate LED is on
}
// Check if the LED is on and if 2 seconds have passed since it was turned on
if (ledOn && (millis() - ledTurnOnTime >= holdTime)) {
digitalWrite(ledPin, LOW); // Turn off the LED
ledOn = false; // Reset flag
}
}
Verify pins. I do not understand the official datasheet, but my notes show "D1" on pin 3 and "A0" on pin 13, named "alternative pinout" (I do not know why) on a few bits of information, but I had a hard time settling on those values.
You say you're using an ATTiny84. That's a 14 pin DIP IC, with as many as 11 I/Os.
In your sketch, you make sure to set unused pins to INPUT_PULLUP. But only 3 of them: 0, 3 and 4. You use 1 for the LED and 2 for the ADC input. You leave 5-8 (or 5-10 if you're not using an external crystal) alone.
That's only 5 I/Os out of 9 (or 11) that get set up. Coincidentally, 5 is the number of I/O pins on an ATTiny85; an 8 pin DIP IC.
Before I delve any deeper into this, can you confirm that you are using the ATTiny84, the 14 pin IC, and not the ATTiny85, the 8 pin IC?
This could be the issue—I may have forgotten to select "Arduino as ISP" under the Tools menu before I uploaded the code. I’ll check when I’m back at the computer in two hours. Thanks!!
Its been a long time but when I last used the ATiny84A (pdip package) I used this code:
Warning, I like to control the device at the register level as it helps me understand how to best use the processor.
You can also see if there are examples in the IDE (Files/example .......)
/*
ADC Test with results printed to PB1
ADC = PA1
Print out = PB1
v2 - works with ADC, SoftSerial, Average time and map
*/
#include <SendOnlySoftwareSerial.h>
uint16_t onTime;
const unsigned int minonTime = 1; // counts
const unsigned int maxonTime = 50;
SendOnlySoftwareSerial mySerial(PIN_PB1);
void setup()
{
DDRA = 0b00000000; //bit(PA0) | bit(PA2) | bit(PA3) | bit(PA4) | bit(PA5) | bit(PA6); // PA7 is an input
DDRB = 0b00000010;
mySerial.begin(9600);
initADC();
mySerial.println("starting...");
}
int i;
void loop()
{
//Read pot and print..
uint16_t PulseTime;
uint16_t ADCsum = 0;
uint8_t i = 0;
for(i=0;i<6;++i){
ADCSRA |= (1 << ADSC); // start ADC measurement
while (ADCSRA & (1 << ADSC) ); // wait till conversion complete
ADCsum += ADCH;
}
uint16_t OnTime = ADCsum/6;
PulseTime = map(OnTime, 0, 255, maxonTime, minonTime);
mySerial.print ("OnTime: ");
mySerial.print (OnTime);
mySerial.print (" PulseTime: ");
mySerial.println (PulseTime);
delay (1000);
}
void initADC()
{
// enable the ADC input pin(s), here we pick PA1.
ADMUX =
(0 << REFS1) | // Sets ref. voltage to Vcc, bit 1
(0 << REFS0) | // Sets ref. voltage to Vcc, bit 0
(0 << MUX5) | // use ADC1 for input (PA1), MUX bit 5
(0 << MUX4) | // use ADC1 for input (PA1), MUX bit 4
(0 << MUX3) | // use ADC1 for input (PA1), MUX bit 3
(1 << MUX2) | // use ADC1 for input (PA1), MUX bit 2
(1 << MUX1) | // use ADC1 for input (PA1), MUX bit 1
(1 << MUX0); // use ADC1 for input (PA1), MUX bit 0
ADCSRA =
(1 << ADEN) | // Enable ADC
(1 << ADPS2) | // set prescaler to 16, bit 2
(0 << ADPS1) | // set prescaler to 16, bit 1
(0 << ADPS0); // set prescaler to 16, bit 0
ADCSRB =
(1 << ADLAR); // left shift result (for 8-bit values)
// (0 << ADLAR); // right shift result (for 10-bit values)
}
The ATTinyCore needs you to use A1 for analogRead, not 2: if you look in pins_arduino.h for the ATTiny85, you'll see that A1 is defined as 0x80 | 1. So change const int signalPin = 2; to const int signalPin = A1;
Your comments are inconsistent. If you want the LED to go out 2 seconds after being turned on, you need to change
if (signalValue >= threshold) {
to
if (!ledOn && signalValue >= threshold) {
The way you have it now, the LED goes off 2 seconds after the signal goes below the threshold. That may be what you want, but "Check if the LED is on and if 2 seconds have passed since it was turned on" isn't the same thing as "Check if the LED is on and if 2 seconds have passed since they signal went below the threshold" .
Thanks, everyone, for your help! The issue turned out to be the pin name in the code. Using "A1" instead of just 2 made everything work as expected. I’ve now successfully uploaded the code to my ATtiny85. This was my first time using the analog pins—I had only used the two digital pins before and just labeled them "0" and "1." Now I understand the importance of the "A" prefix and the distinction between digital and analog pins.
Yes the description was a little bit wrong. What I ment was that the led should stay on for 2 seconds after the signal goes below the threshold. Thanks
Final working code:
const int signalPin = A1; // The analog pin reading the DC signal
const int ledPin = 1; // The digital pin controlling the LED
const int threshold = 11; // -23 dBu
const unsigned long holdTime = 2000; // Time in milliseconds to hold LED on
unsigned long ledTurnOnTime = 0; // To track when the LED was turned on
bool ledOn = false; // To track the LED state
// Define unused pins
const int ncPin0 = 0; // Not connected
const int ncPin3 = 3; // Not connected
const int ncPin4 = 4; // Not connected
void setup() {
pinMode(ledPin, OUTPUT); // Set LED pin as an output
pinMode(signalPin, INPUT); // Set signal pin as input
// Set unused pins to input pull-up mode
pinMode(ncPin0, INPUT_PULLUP);
pinMode(ncPin3, INPUT_PULLUP);
pinMode(ncPin4, INPUT_PULLUP);
}
void loop() {
int signalValue = analogRead(signalPin); // Read the analog signal
// If signal is above threshold, turn on LED and record the time
if (signalValue >= threshold) {
digitalWrite(ledPin, HIGH); // Turn on the LED
ledTurnOnTime = millis(); // Record the time the LED was turned on
ledOn = true; // Set flag to indicate LED is on
}
// Check LED and stay on for 2 seconds after the signal goes below the threshold
if (ledOn && (millis() - ledTurnOnTime >= holdTime)) {
digitalWrite(ledPin, LOW); // Turn off the LED
ledOn = false; // Reset flag
}
}