Вольтметр + контроль освещенности для автомобиля
- Войдите на сайт для отправки комментариев
Втр, 23/05/2017 - 14:28
Доброго времени суток!
Описываю ситуацию:
имеется автомобильное головное устройство (ГУ) на андроиде, есть идея прикрутить к нему ардуино для регулировки яркости экрана в зависимости от освещения и вывода напряжения бортовой сети на экран, при помощи SerialManager (ссылка).
Для это была взята ардуино нано и подключена следующим образом
залит скетч такого вида
#include <MsTimer2.h>
#include <SimpleTimer.h>
SimpleTimer timer; // таймер измерения освещения
int sens = 0;
int sens_save;
int light = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 150000.0; // сопротивление R1 (150K)
float R2 = 50500.0; // сопротивление R2 (51K)
int value = 0;
void setup()
{
Serial.begin(115200);
pinMode(3, INPUT);
MsTimer2::set(5000, timerInterupt); // установка интервала таймера вольтметра 5 сек.
MsTimer2::start(); //запуск таймера вольтметра
timer.setInterval(500, brightcheck); // установка интервала таймера измерения освещения 0,5 сек.
}
// запуск таймера измерения освещения
void loop()
{
timer.run();
}
// измерение уровня яркости освещения
void brightcheck()
{
sens = analogRead(1);
sens = map(sens, 0, 1000, 0, 100); // для упрощения калибровки фоторезистора "map(sens, нижний порог, верхний порог, 0, 100)"
sens = constrain(sens, 0, 100); // числовые показания ограничены диапазоном от 0 до 100
if (abs(sens_save - sens) > 5)
{
if (sens<10) light = 0;
if ((sens > 10) && (sens<20)) light = 2;
if ((sens > 20) && (sens<30)) light = 5;
if ((sens > 30) && (sens<40)) light = 10;
if ((sens > 40) && (sens<50)) light = 20;
if ((sens > 50) && (sens<60)) light = 35;
if ((sens > 60) && (sens<70)) light = 50;
if ((sens > 70) && (sens<80)) light = 70;
if (sens > 80) light = 100;
String s = "<brightness:" + String(light) + "%>";
Serial.print(s);
sens_save = sens;
}
}
// обработчик прерывания 5 с
void timerInterupt()
{
value = analogRead(3); // считывание аналогового значения напряжения
vout = (value * 5.0) / 1024.0;
vin = vout / (R2/(R1+R2));
String u = "<volt:" + String(vin) + ">";
Serial.print(u);
}
По таймеру SimpleTimer.h каждые 0,5 сек измеряется освещенность на А1, при изменении на 5 (по шкале от 0 до 100) данные отсылаются в ком-порт. MsTimer2.h каждые 5 сек прерывает для измерения напряжения на А3 и также отсылает значение в ком-порт.
Питание ардуины идет через USB, подключенной в активный USB-хаб, который, в свою очередь, подключен к USB входу ГУ.
Теперь собственно проблема: на комп порт данные яркости отправляются как положено (при изменении освещенности > 10), а вот показания вольтметра постоянно скачут (при поданных на А3 честных 12,0 В), при чем при изменении освещенности в меньшую сторону, вольтаж, выводимый в ком-порт соответственно падает (при полной темноте показывает почти 0В, но на входе-то остаются всё те же 12В).
Подскажите, пожалуйста, в чем проблема? Почему вольтметр имеет такую зависимость от фоторезистора?

Опишите R1, R2, value, vout и vin внутри функции timerInterupt - с какого перепугу им быть глобальными.
Или, если уж так хочется сделать их глобальными, то хотя бы опишите как volatile.
Сделайте, а там посмотрим.
А зачем использовать 2 разных библиотеки таймера? если все можно сделать на одной?
Опишите R1, R2, value, vout и vin внутри функции timerInterupt - с какого перепугу им быть глобальными.
Или, если уж так хочется сделать их глобальными, то хотя бы опишите как volatile.
Сделайте, а там посмотрим.
Спасибо, вечером попробую.
А зачем использовать 2 разных библиотеки таймера? если все можно сделать на одной?
Не придумал ничего лучше, чтоб сделать опрос входов с разными интервалами времени. Я в "ардуиностроении" новичёк, если подскажете как запихнуть всё в одну библиотеку, буду благодарен.
Опишите R1, R2, value, vout и vin внутри функции timerInterupt - с какого перепугу им быть глобальными.
Или, если уж так хочется сделать их глобальными, то хотя бы опишите как volatile.
Сделайте, а там посмотрим.
Спасибо, вечером попробую.
А зачем использовать 2 разных библиотеки таймера? если все можно сделать на одной?
Не придумал ничего лучше, чтоб сделать опрос входов с разными интервалами времени. Я в "ардуиностроении" новичёк, если подскажете как запихнуть всё в одну библиотеку, буду благодарен.
Ну типа того, в принципе SimpleTimer может создавать много вызовов как цикличных так и одиночных тут вот подробнее можно прочитать - https://playground.arduino.cc/Code/SimpleTimer
Переделал код на одну библиотеку и с учетом замечаний ЕвгенийП
Не сказать что код оптимален, но это уж сами. В IDE 1.8.2 компилируется без ошибок.
#include <SimpleTimer.h> SimpleTimer timer; // таймер измерения освещения void setup() { Serial.begin(115200); pinMode(3, INPUT); timer.setInterval(500, brightcheck); // установка интервала таймера измерения освещения 0,5 сек. timer.setInterval(5000, timerInterupt); // установка интервала таймера вольтметра 5 сек. } // запуск таймера измерения освещения void loop() { timer.run(); } // измерение уровня яркости освещения void brightcheck() { int sens = 0; static int sens_save = 0; int light = 0; sens = analogRead(1); sens = map(sens, 0, 1000, 0, 100); // для упрощения калибровки фоторезистора "map(sens, нижний порог, верхний порог, 0, 100)" sens = constrain(sens, 0, 100); // числовые показания ограничены диапазоном от 0 до 100 if (abs(sens_save - sens) > 5) { if (sens < 10) light = 0; if ((sens > 10) && (sens < 20)) light = 2; if ((sens > 20) && (sens < 30)) light = 5; if ((sens > 30) && (sens < 40)) light = 10; if ((sens > 40) && (sens < 50)) light = 20; if ((sens > 50) && (sens < 60)) light = 35; if ((sens > 60) && (sens < 70)) light = 50; if ((sens > 70) && (sens < 80)) light = 70; if (sens > 80) light = 100; String s = "<brightness:" + String(light) + "%>"; Serial.print(s); sens_save = sens; } } // обработчик прерывания 5 с void timerInterupt() { float vout = 0.0; float vin = 0.0; float R1 = 150000.0; // сопротивление R1 (150K) float R2 = 50500.0; // сопротивление R2 (51K) int value = 0; value = analogRead(3); // считывание аналогового значения напряжения vout = (value * 5.0) / 1024.0; vin = vout / (R2 / (R1 + R2)); String u = "<volt:" + String(vin) + ">"; Serial.print(u); }асинхронный многотаймеров.
https://github.com/DetSimen/Arduino-
обращайся, помогу, еслишто.
Переделал код на одну библиотеку и с учетом замечаний ЕвгенийП
Опробовал код, ситуция не поменялась, вот кусок вывода данных в ком-порт
Значения измеряемого напряжения по-прежнему почему-то зависят от освещённости, такое ощущение, что в схеме подключения что-то не так, но не могу понять что. Вроде аналоговые входы никак не связаны между собой, кроме земли.
Очень странный результат. Вы правильно пользуетесь таймерами? Дело в том, что brightness должно печататься в 10 раз чаще, чем напряжение.
Давайте сделаем так:
1. В печать добавляете значение millis()
2. вместо print используете println, чтобы каждое значение было на отдельной строке
Как сделаете, выложите актуальный скетч, копипасты напечатанного лога и схему включения.
Очень странный результат. Вы правильно пользуетесь таймерами? Дело в том, что brightness должно печататься в 10 раз чаще, чем напряжение.
Давайте сделаем так:
1. В печать добавляете значение millis()
2. вместо print используете println, чтобы каждое значение было на отдельной строке
Как сделаете, выложите актуальный скетч, копипасты напечатанного лога и схему включения.
У меня код измерения освещенности выводит новое значение только при изменении освещенности >5, чтоб не засорять ком-порт каждые полсекунды. Схема подключения в первом сообщении.
Narkus, у вас и код и схема с разного рода недочётами. Но примитивность скечта тут вряд ли оказывает влияние, скорее всё таки аппаратные недоработки. В частности 50 кОм со входа на землю -слишком много. максимум 10k, а лучше меньше. Например делитель из 4к7 и 12к. Либо можно повесить паралельно входу конденсатор 100n, но по последним данным это вредит точности) Так что лучше уменьшать резистор.
Narkus, у вас и код и схема с разного рода недочётами. Но примитивность скечта тут вряд ли оказывает влияние, скорее всё таки аппаратные недоработки. В частности 50 кОм со входа на землю -слишком много. максимум 10k, а лучше меньше. Например делитель из 4к7 и 12к. Либо можно повесить паралельно входу конденсатор 100n, но по последним данным это вредит точности) Так что лучше уменьшать резистор.
О, спасибо, попробую.