Здравствуйте, собираю простенький измерительный прибор на ATtiny85.
Помогите с обвязкой голой ATtiny85, сейчас при измерении батарейки показания на дисплее постоянно прыгают от 1.2 до 2.4, что мне нужно добавить из радиодеталей, что бы показания не прыгали?
Подключение такое.
В коде измеряю так:
#include <avr/io.h>
#include <util/delay.h>
#define PIN_A2 A2
#define PIN_P1 3 //Назначаем пин P1
float R1_R4 = 108.9; //Сопротивление резистора R1 + R4 в кОм 98.9 + 10
float R2 = 9.7; //Сопротивление резистора R2 в кОм 9.7
#define OLED_ADDR 0x78
#define OLED_CMD_MODE 0x00
#define OLED_DAT_MODE 0x40
#define DISPLAY_INIT_LEN 15
#define I2C_SDA PB0
#define I2C_SCL PB1
#define I2C_SDA_HIGH() DDRB &= ~(1<<I2C_SDA)
#define I2C_SDA_LOW() DDRB |= (1<<I2C_SDA)
#define I2C_SCL_HIGH() DDRB &= ~(1<<I2C_SCL)
#define I2C_SCL_LOW() DDRB |= (1<<I2C_SCL)
uint16_t VOLT = 0;
uint8_t DATA[5] = {};
float DEFAULT_VOLT = 0; //Напряжение по умолчанию;
float VOLT_DISPLAY = 0; //Объявляем переменную для хранения значения напряжения
uint16_t AVERAGE_VOLT = 0;
unsigned long TIME = 0; //Объявляем переменную таймера задержки измерений
#include "DISPLAY.h"
void setup()
{
DISPLAY_INIT();
pinMode(PIN_P1, OUTPUT); //Пин установлен на выход
pinMode(PIN_A2, INPUT); //Пин установлен на вход
DEFAULT_VOLT = GET_DEFAULT_VOLT(); //Измеряем внутреннее напряжение
}
void loop()
{
if (millis() - TIME <= 200) //Добавляем задержку в 200 миллисекунд
return;
TIME = millis();
//DEFAULT_VOLT = GET_DEFAULT_VOLT();
DISPLAY_CLEAR();
VOLT_DISPLAY = analogRead(PIN_A2) * DEFAULT_VOLT / 1024 * (( R1_R4 + R2 ) / R2); //Рассчитываем значение напряжения
if (VOLT_DISPLAY >= 0.7) //Если напряжение больше 0.7 вольт, значит плюс
{
if (digitalRead(PIN_P1) == HIGH) //Подаём прерывистый звуковой сигнал
digitalWrite(PIN_P1, LOW);
else
digitalWrite(PIN_P1, HIGH);
}
else if (VOLT_DISPLAY < 0.7 && VOLT_DISPLAY >= 0.3) //Если напряжение в диапазоне от 0.3 до 0.7 вольт, значит масса
{
digitalWrite(PIN_P1, HIGH); //Подаём непрерывистый звуковой сигнал
}
else if (VOLT_DISPLAY < 0.3) //Если напряжение ниже 0.3 вольт
{
digitalWrite(PIN_P1, LOW); //Отключаем звуковой сигнал
}
if (VOLT_DISPLAY >= 10) //Напряжение больше 10 вольт
{
VOLT = VOLT_DISPLAY * 100; //Сдвигаем значение напряжение на 2 бита влево
}
else //Напряжение меньше 10 вольт
{
VOLT = VOLT_DISPLAY * 1000; //Сдвигаем значение напряжение на 3 бита влево
}
if (VOLT_DISPLAY >= 0.7 || VOLT_DISPLAY < 0.3) //Если напряжение больше 0.7 вольт и меньше 0.3 вольта
{
DATA[0] = VOLT / 1000;
DATA[1] = VOLT_DISPLAY >= 10 ? (VOLT % 1000) / 100 : 16;
DATA[2] = VOLT_DISPLAY >= 10 ? 16 : (VOLT % 1000) / 100;
DATA[3] = (VOLT % 100) / 10;
DATA[4] = VOLT % 10;
DISPLAY_PRINT(DATA);
}
else //Иначе
{
DATA[0] = 10;
DATA[1] = 11;
DATA[2] = 12;
DATA[3] = 13;
DISPLAY_PRINT(DATA); //Отображаем на дисплее слово MASS
}
}
float GET_DEFAULT_VOLT() { //Функция измеряет внутреннее напряжение Arduino
long RESULT = 0; //Определяем переменную для получения результата.
byte COUNT_RESULT = 100; //Определяем сколько значений АЦП требуется получить для усреднения результата.
//Для Arduino Mega, Leonardo и Micro, сбрасываем бит «MUX5» регистра «ADCSRB», так как «MUX[5-0]» должно быть равно 011110 (см. регистр «ADMUX»).
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //Устанавливаем биты регистра «ADMUX»: «REFS»=01 (ИОН=VCC), «ADLAR»=0 (выравнивание результата по правому краю), «MUX[4-0]»=11110 или «MUX[3-0]»=1110 (источником сигнала для АЦП является напряжение ИОН на 1,1 В).
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
for(byte i=0; i<COUNT_RESULT; i++) //Получаем несколько значений АЦП
{
ADCSRA |= _BV(ADSC); //Запускаем преобразования АЦП:Устанавливаем биты регистра «ADCSRA»: «ADEN»=1 (вкл АЦП), «ADSC» =1 (запускаем новое преобразование).
while (bit_is_set(ADCSRA, ADSC)); //Получаем данные АЦП:
uint8_t _LOW = ADCL;
uint8_t _HIGH = ADCH;
RESULT += (_HIGH << 8) | _LOW; //Суммируем результат
}
RESULT /= COUNT_RESULT; //Делим результат «RESULT» на «COUNT_RESULT», так как мы получили его «COUNT_RESULT» раз.
return (1.1f/RESULT) * 1024; //Рассчитываем напряжение питания: // АЦП = (Uвх/Vcc)*1023. Напряжение Uвх мы брали с внутреннего ИОН на 1.1 В, значение которого возвращает функция analogSave_1V1(0).
}