I am trying to program my ATtiny85 to take in four analog inputs (from thermistors) and output a PWM signal at the maximum voltage if any of the inputs exceed a threshold voltage. If the thermistors exceed that max voltage, the output should stay high until it drops below a minimum voltage.
Considering the 10-bit adc in the ATtiny85, I derived the following:
Max Voltage (1.934 Volts) = 550
Min Voltage (1.869 Volts) = 531
Step size = 284.166 (Vcc = 3.6v)
Not sure why, but all pins are remaining low (except reset and vcc) even when a voltage over the threshold I set is applied to any of the inputs. My code is below.
#define MOTOR_PIN 6 //pwm1
#define INPUT_1 5 //Ain0 this is the reset pin
#define INPUT_2 7 //Ain1
#define INPUT_3 3 //Ain2
#define INPUT_4 2 //Ain3
// ATMEL ATTINY45 / ARDUINO this is the pinout for 85
//
// +-\/-+
// Ain0 (D 5) PB5 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0
//
void setup() {
pinMode(MOTOR_PIN, OUTPUT); // Set pin 6 as output for digital output
//set pins pb2-pb5 as inputs
pinMode(INPUT_1, INPUT);
pinMode(INPUT_2, INPUT);
pinMode(INPUT_3, INPUT);
pinMode(INPUT_4, INPUT);
}
void loop() {
//read analog input for all inputs and store in val var
int val1 = analogRead(INPUT_1);
int val2 = analogRead(INPUT_2);
int val3 = analogRead(INPUT_3);
int val4 = analogRead(INPUT_4);
//check to see if the values have surpassed threshold voltage 1.934027489
if(val1 > 550 || val2 > 550 || val3 > 550 || val4 > 550){
//start a loop to hold input high until drops below 1.869397173
while(val1 > 531 || val2 > 531 || val3 > 531 || val4 > 531){
analogWrite(MOTOR_PIN,255); // set output to high voltage signal 3.6vref, pwm based on 10 bit binary hence 1023
}
}
//when the voltages did not exceed max, or dropped below min
else{
analogWrite(MOTOR_PIN,0); //set output to zero
}
}
That is true, you can use the reset pin as an input, however the voltage may not below Vcc / 2, or the ATtiny will reset. The effective range is therefore reduced by half, and usually it is best to leave a fair margin.
There are for Analog pins available, and best is to just call them by their name.
#define INPUT_1 5 //Ain0 this is the reset pin
#define INPUT_2 7 //Ain1
#define INPUT_3 3 //Ain2
#define INPUT_4 2 //Ain3
should be
#define INPUT_1 A0 //this is the reset pin
#define INPUT_2 A1
#define INPUT_3 A2
#define INPUT_4 A3
I think you can also name them with there GPIO name
#define INPUT_1 5 //this is the reset pin
#define INPUT_2 2
#define INPUT_3 4
#define INPUT_4 3
I haven't looked at the rest of your code, let's fix this first.
There is also the option to use the reset pin normally, by using the fuse settings, but you can not re-program the ATtiny thereafter without the use of a high-voltage programmer.
Note that you can in fact set the RESET pin to be a normal I/O pin by setting a so-called fuse in the processor. However if you do so, you need a high voltage programmer to be able to program the ATtiny, as it needs a 12V pulse to the RESET pin to go into programming mode.
It is much easier to go for a slightly larger (and cheaper!) MCU like the 14-pin ATtiny84a, or the newer 8-pin ATtiny402, which can do four analog in and one PWM out without needing to mess with the reset pin.
Thank you! I have been getting confused with the pinouts... I will go by the ones on the sparkfun website. The core I chose has a different layout in the README file, and even more different ones with a google search
Its a bummer that I cant get a fourth. Im on a time crunch, so the ATtiny84a is not an option. Wish I saw that one first.
I have updated my code to take into account no input on the reset pin. I have decreased the inputs to include only A1-3. However, the output is still consistently high. Interestingly, it is only outputting 2.6 volts, one volt less than the supply (aprx).
I attached the updated code.
#define MOTOR_PIN 0 //pwm0 D0 PB0 5
#define INPUT_1 A0 //Ain0 D5 PB5 1 this is the reset pin DO NOT USE THIS ALWAYS HIGH
#define INPUT_2 A1 //Ain1 D2 PB2 7
#define INPUT_3 A2 //Ain2 D4 PB4 3
#define INPUT_4 A3 //Ain3 D3 PB3 2
// ATMEL ATTINY45 / ARDUINO this is the pinout for 85
//
// +-\/-+
// Ain0 (D 5) PB5 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0
//
void setup() {
pinMode(MOTOR_PIN, OUTPUT); // Set pin 6 as output for digital output
//set pins input_n as inputs
pinMode(INPUT_1, INPUT); //THE PROBLEM!!
pinMode(INPUT_2, INPUT);
pinMode(INPUT_3, INPUT);
pinMode(INPUT_4, INPUT);
}
void loop() {
//read analog input for all inputs and store in val var
//int val1 = analogRead(INPUT_1);
int val2 = analogRead(INPUT_2);
int val3 = analogRead(INPUT_3);
int val4 = analogRead(INPUT_4);
//check to see if the values have surpassed threshold voltage 1.934027489
if (/*val1 > 550 || */val2 > 550 || val3 > 550 || val4 > 550) {
//start a loop to hold input high until drops below 1.869397173
while (/*val1 > 531 || */val2 > 531 || val3 > 531 || val4 > 531) {
analogWrite(MOTOR_PIN, 255); // set output to high voltage signal 3.6vref, pwm based on 10 bit binary hence 1023
//int val1 = analogRead(INPUT_1);
int val2 = analogRead(INPUT_2);
int val3 = analogRead(INPUT_3);
int val4 = analogRead(INPUT_4);
}
}
//when the voltages did not exceed max, or dropped below min
else {
analogWrite(MOTOR_PIN, 0); //set output to zero
}
}
I have run blink on this ATtiny, worked well. I also ran a program that changed the intensity of the PWM signal and applied it to an LED, changing the brightness. This program also worked. it is powering the gate of a BJT, so not much power is needed.
yes, but as i said, you should make sure it never reaches less voltage than half of Vcc, the easiest is by using a resistor to create a voltage divider with the sensor, or you may nee to use a transistor of some kind, and recalculate the values for Low and High threshold.
The fuse settings are tricky to get working.
If you upload the blink example first, you can see how you can safely attach the sensor without the Attiny resetting.
Depends on your overall circuit.
The measurements you give strongly suggest a wiring error.
Now if you had posted your schematic we'd not have to make guesses, educated or not...
This is similar to the style I have implemented now, however the voltage from the divider is right on the cusp at 1.8v, i can try changing the Rbias to bring it a bit higher… I will post the schematics shortly
I would do that, actually when the sensor is not connected you should be easily above the threshold. Oh hey guys get some avatars, i have to look so closely to see who said what.
3. When considering analog pins, the definitions in the ATTinyCore are: (There is no need to set the directions of A0 to A4 as INPUTs; they have already benn configuredas INPUTs in the Core/Arduino.h.)
int val1 = analogRead(A0); //ADC0
int val2 = analogRead(A1); //ADC1
int val3 = analogRead(A2); //ADC2
int val4 = analogRead(A3); //ADC3
4. If Pin-1 is being used NOT as an IO but as a RESET/-pin, then an external DC voltage (2.8V to 5V) can be acquired by executing int val1 = analogRead(A0). If an external voltage less than 2.8V is applied at the RESET/-pin, the MCU will be at RESET state (Fig-1).
These are the circuit schematics excluding the MCU. R4 represents the internal resistance of the vibration motor in use. it requires 60 mA (80 mA max) and a max operating voltage of 3.6 volts. VEE should be 3.6 volts not 1.8.