#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
//result = 1125300L / result; // Back-calculate AVcc in mV - первый запуск для калибровки с этой строкой, следующию комментируем
/* Повышаем точность
Пока большие допуски внутреннего источника питания 1.1 В. значительно ограничивают точность
измерений при использовании в серийном производстве, для индивидуальных проэктов мы можем добиться
большей точности. Сделать это просто, просто измерив Vcc с помощью вольтметра и нашей функции показаний Ардуины.
Далее заменяем константу 1125300L новой переменной:
scale_constant = internal1.1Ref * 1023 * 1000
где
internal1.1Ref = 1.1 * Vcc1 (показания_вольтметра) / Vcc2 (показания_Ардуины)
Это калиброванное значение будет хорошим показателем для измерений AVR чипом,
но может зависеть от изменений температуры. Не стесняйтесь экспериментировать с вашим собственным измерениям.
*/
result = 1.1 * 3.63 / 3.66 * 1023 * 1000 / result; // я откалибровал так 3.66 - пказания ардуно, 3.63 - пказания вольтметра, калиброва лучше на средних значениях
return result;
}
void setup() {
lcd.begin(16, 2);
lcd.clear();
}
void loop() {
unsigned int ADCValue;
double Voltage;
double Vcc;
Vcc = readVcc()/1000.0;
ADCValue = analogRead(3);
Voltage = (ADCValue / 1023.0) * Vcc;
//Voltage = Voltage / (16.0 / (52.0 + 16.0)); // R2/(R1+R2) // если больше 5 Вольт ставим делитель
lcd.setCursor(0, 1);
lcd.print(Voltage);
lcd.print(" V ");
delay(1000);
}
Надо будеь посмотрть чистый millis как работает
ПС: полный скейтч программы смогу выложить только во вторник
Так и берите секундные интервалы от часов. Погрешность небольшая будет, но думаю это не критично. Главное, чтобы основной цикл у вас не длился больше секунды. Без delay-ев этого достичь сложно.
Спасибо. А меньше секунды не получится сделать? ПС: В нете полно проектов-секундомеров даже с микросекундами - да кому и зачем он с такой погрешностью нужен?
Вы заказали секунду, я по ней ответил в наиболее простой реализации. А так на том модуле должен быть выход SQ (может ошибаюсь) на нем можете получить такты от 32768 до 1Гц и использовать их как опорные.
Покрутил DS3231 так и не понял как использовать её в моём проекте - запускать каждую секунду это легко: Alarm.timerRepeat(1, Repeats); , а вот как это остановить?
Устанавливаете на выходе SQ требуемую частоту, выход на вход прерывания дуины (помним про подтяжку, возможно она уже на шилде разведена). Далее курим: http://arduino.ru/Reference/AttachInterrupt
Помним - в прерывании находится минимально возможное время (в идеале поднять флаг или изменить счетчик), в loop постоянно мониторим переменную изменяемую в прерывании, когда условие стало true - выполняем нужную нам функцию, сбрасываем переменную. Все пошло по новой. Как то так.
unsigned longwatch_millis;//значение millis() для текущего времени int watch(int watch_t)//расчет текущего времени в минутах{
unsigned long time_;int watch_delta;
time_ = millis();
watch_delta =int((time_ - watch_millis)/60000);// изменение в минутахif(watch_delta>0){
watch_millis = time_;}if(watch_t + watch_delta >1439)return0;elsereturn watch_t + watch_delta;}
Пример использования
int watch_time=0;//текущее время в минутах(00:00 - 23:59)void loop(){
watch_time=watch(watch_time);//получаем новое значение времени}
unsigned long watch_millis;//значение millis() для текущего времени int watch(int watch_t)//расчет текущего времени в минутах{
unsigned long time_;int watch_delta;
time_ = millis();
watch_delta =int((time_ - watch_millis)/60000);// изменение в минутахif(watch_delta>0){
watch_millis = time_;}if(watch_t + watch_delta >1439)return0;elsereturn watch_t + watch_delta;}
noxic, а вы хоть тему читали? ТС по этим граблям уже ходил. Не работает у него millis() с SD-шкой. Да и код в менее извращенном виде можно вставлять, глаза ведь не железные.
Устанавливаете на выходе SQ требуемую частоту, выход на вход прерывания дуины (помним про подтяжку, возможно она уже на шилде разведена). Далее курим: http://arduino.ru/Reference/AttachInterrupt
Помним - в прерывании находится минимально возможное время (в идеале поднять флаг или изменить счетчик), в loop постоянно мониторим переменную изменяемую в прерывании, когда условие стало true - выполняем нужную нам функцию, сбрасываем переменную. Все пошло по новой. Как то так.
Подтяжка вроде уже есть - резисторная сборка 4,7 кОм
Кроме 30 и 33 строки больше ничего в прерывании быть не должно. Зашли, что то изменили, тут же вернулись.
Не хочу даташит искать, а что у вас Vrem делает?
А куда тогда мне засунуть считование показаний вольтметра и запись на СД?
Vrem - это прсто переменная с помощью её я просто вижу через какое время запустилось и сколько раз.
ПС: мне 1,2,18,24 и 30 строки не нужны - это просто светодиод моргает. Мне просто нужно чтоб каждую секунду считывался вольтметр и его показания писались на СД и если аккумулятор меньше 3-х вольт - разрывалась нагрузка и программа останавливалась
Поставили в прерывании вашу state=1; вышли, по этому условию в loop произвели замер и запись, сделали state=0; loop крутится, ждет когда state снова будет 1.
Поставили в прерывании вашу state=1; вышли, по этому условию в loop произвели замер и запись, сделали state=0; loop крутится, ждет когда state снова будет 1.
Если работает, то вроде да. Из мелких придирок, зачем Vrem объявлена float? Она по вашему коду может когда либо принять значение с десятичным знаком или превысить 255? Старайтесь использовать только типы, необходимые для выполнения программы, кроме экономии памяти это спасет вас от граблей. Попробуйте конструкцию if (Vrem == 25), большие шансы, что она не сработает.
Кварц, даже самый гнилой и самый китайский, не может ошибаться на "примерно 10 сенунд в минуту" или "в минуту почти на 15 секунд".
Я бы, всё-таки, постарался выяснить в чём дело. Там или действительно кварц не на ту частоту, или частота неправильно указана в настройках проекта, или этот кварц вообще отключен какими-нибудь фьюзами.
Ну, или программа написана всё же неправильно - бывает и такое, в конце концов.
У меня был случай с Про Мини. Скетчи на ней выполнялись в десять раз медленнее чем на других ардуинках. Так как в каких-то там фьюзах не понимаю, я просто по совету (извините, не помню кого) с этого форума, просто перезаписал загрузчик. Проблема исчезла. Ардуинка стала работать нормально.
Если работает, то вроде да. Из мелких придирок, зачем Vrem объявлена float? Она по вашему коду может когда либо принять значение с десятичным знаком или превысить 255? Старайтесь использовать только типы, необходимые для выполнения программы, кроме экономии памяти это спасет вас от граблей. Попробуйте конструкцию if (Vrem == 25), большие шансы, что она не сработает.
1 В данном случае Вы правильно подметили, в полной версии моей программы Vrem считает секунды-циклы и это значение пишется на СД карту и его значение будет 0 - 3000.
2 программа будет останавливается если батарея разредилась меньше 3-Вольт и возможно ==3 проскочит и не сработает.
Вы меня не совсем поняли по float, c напряжением на батарее если не принимать никаких мер, придется мирится с вещественным числом. А там где вы оперируете целыми числами при конструкции типа float a=25*4/5 сравнение if(a==20) из за особенности представления вещественного числа в памяти может оказатся ложным. Это надо учитывать
Вы меня не совсем поняли по float, c напряжением на батарее если не принимать никаких мер, придется мирится с вещественным числом. А там где вы оперируете целыми числами при конструкции типа float a=25*4/5 сравнение if(a==20) из за особенности представления вещественного числа в памяти может оказатся ложным. Это надо учитывать
Так исправлять не надо. Просто помнить, что == на float часто ведет себя не как планировалось. Соответственно >= или <=.
А так почему нельзя разделить?
int x;
int y;
float z;
x = 1;
y = x / 2; // y теперь равен 0, тип int не может хранить дробные числа
z = (float)x / 2.0; // z равна .5 (следует использовать 2.0, а не 2)
Не знаю правильно ли я понял проблему. Но мне кажется что if(a==20) нужно заменить на if(a<20). При первом же ближайшем значении все сработает как надо.
Действительно все выходит, тоже проверил. Но один раз проскочил по таким граблям, как там сложились условия уже не помню, но пока обнаружил грязь в последнем разряде крови много себе попортил.
Что то у меня сомнение по поводу подтяжки - на модуле стоит подтяжка к 3,3В т.е. после регулятора напряжения тока SOT-23 10pcs XC6206P332MR (662K) 3.3V/0.5A
А свои millis-ы проверьте тупым счетчиком за час или за сутки. Согласен с Datak, что скорее всего у вас кривая программа. Такой ошибки быть не может.
Возможно Вольтметр мешает - вот скетч вольтметра:
Надо будеь посмотрть чистый millis как работает
ПС: полный скейтч программы смогу выложить только во вторник
Тормозит запись СД - если неё убрать то оотставание 30-35сек в час
Это уже ближе к телу, хотя все равно много. Все таки проверьте чистый millis(). Предполагаю, что нормальное значение - 3-5сек.
Это уже ближе к телу, хотя все равно много. Все таки проверьте чистый millis(). Предполагаю, что нормальное значение - 3-5сек.
За 10мин максимум секунда
в следующий раз поточней измерю
Чистый millis - за час отстал на 4 секунды
Чистый millis - за час отстал на 4 секунды
Вот это наверно уже реальная ошибка, хотя за сутки было бы точнее.
Чистый millis - за час отстал на 4 секунды
Вот это наверно уже реальная ошибка, хотя за сутки было бы точнее.
Таймер и millis почему то останавливаются при записи на СД карту - это хорошо видно если сделать запись 10 раз.
Это нормально или millis должен считать пока ардуино пишет на СД?
Чистый millis - за час отстал на 4 секунды
Вот это наверно уже реальная ошибка, хотя за сутки было бы точнее.
Таймер и millis почему то останавливаются при записи на СД карту - это хорошо видно если сделать запись 10 раз.
Это нормально или millis должен считать пока ардуино пишет на СД?
Не знаю. Скорее всего такая реализация библиотеки. При нормальных условиях millis() останавливатся не должен. Может другие что присоветуют.(((
Используйте RTC, независящие от тактов ардуинки.
Все же, время тратится на запись на SD, таймер arduino работает на прерываниях, по идее, несколько тактов может захватить код записи на SD.
https://code.google.com/p/arduino/source/browse/trunk/hardware/cores/arduino/wiring.c?r=565
В Вашем случае возможно будет лучше использовать http://arduino.ru/Reference/Micros
Чистый millis - за час отстал на 4 секунды
Вот это наверно уже реальная ошибка, хотя за сутки было бы точнее.
Таймер и millis почему то останавливаются при записи на СД карту - это хорошо видно если сделать запись 10 раз.
Это нормально или millis должен считать пока ардуино пишет на СД?
Не знаю. Скорее всего такая реализация библиотеки. При нормальных условиях millis() останавливатся не должен. Может другие что присоветуют.(((
Скетч пост №53
Удалял всё кроме таймера и СД и выводил millis на экран, тормозит при записи СД - если карту вытащить всё ОК
Буду брать JY-MCU mini_RTCpro DS3231
Вот думаю взять Arduino Compatible Keyes USB Host Shield - как я понял к нему надо брать МЕГУ
Так и берите секундные интервалы от часов. Погрешность небольшая будет, но думаю это не критично. Главное, чтобы основной цикл у вас не длился больше секунды. Без delay-ев этого достичь сложно.
Вы заказали секунду, я по ней ответил в наиболее простой реализации. А так на том модуле должен быть выход SQ (может ошибаюсь) на нем можете получить такты от 32768 до 1Гц и использовать их как опорные.
Покрутил DS3231 так и не понял как использовать её в моём проекте - запускать каждую секунду это легко: Alarm.timerRepeat(1, Repeats); , а вот как это остановить?
А примеры есть по использованию опорных тактов?
Устанавливаете на выходе SQ требуемую частоту, выход на вход прерывания дуины (помним про подтяжку, возможно она уже на шилде разведена). Далее курим: http://arduino.ru/Reference/AttachInterrupt
Помним - в прерывании находится минимально возможное время (в идеале поднять флаг или изменить счетчик), в loop постоянно мониторим переменную изменяемую в прерывании, когда условие стало true - выполняем нужную нам функцию, сбрасываем переменную. Все пошло по новой. Как то так.
Скетч счетчика времени в 24 часовом формате.
Отсчет происходит в минутах!
Пример использования
noxic, а вы хоть тему читали? ТС по этим граблям уже ходил. Не работает у него millis() с SD-шкой. Да и код в менее извращенном виде можно вставлять, глаза ведь не железные.
Устанавливаете на выходе SQ требуемую частоту, выход на вход прерывания дуины (помним про подтяжку, возможно она уже на шилде разведена). Далее курим: http://arduino.ru/Reference/AttachInterrupt
Помним - в прерывании находится минимально возможное время (в идеале поднять флаг или изменить счетчик), в loop постоянно мониторим переменную изменяемую в прерывании, когда условие стало true - выполняем нужную нам функцию, сбрасываем переменную. Все пошло по новой. Как то так.
Подтяжка вроде уже есть - резисторная сборка 4,7 кОм
Вот как то так
Кроме 30 и 33 строки больше ничего в прерывании быть не должно. Зашли, что то изменили, тут же вернулись.
Не хочу даташит искать, а что у вас Vrem делает?
Кроме 30 и 33 строки больше ничего в прерывании быть не должно. Зашли, что то изменили, тут же вернулись.
Не хочу даташит искать, а что у вас Vrem делает?
А куда тогда мне засунуть считование показаний вольтметра и запись на СД?
Vrem - это прсто переменная с помощью её я просто вижу через какое время запустилось и сколько раз.
ПС: мне 1,2,18,24 и 30 строки не нужны - это просто светодиод моргает. Мне просто нужно чтоб каждую секунду считывался вольтметр и его показания писались на СД и если аккумулятор меньше 3-х вольт - разрывалась нагрузка и программа останавливалась
Поставили в прерывании вашу state=1; вышли, по этому условию в loop произвели замер и запись, сделали state=0; loop крутится, ждет когда state снова будет 1.
Ой, чертежи попутал, у вас state диодиком мигает. Короче любую переменную используйте в качестве флага (событие произошло)
И зачем у вас state int-ом инициирована, у нее всего два состояния, а не 65535. boolean или byte.
Поставили в прерывании вашу state=1; вышли, по этому условию в loop произвели замер и запись, сделали state=0; loop крутится, ждет когда state снова будет 1.
Понял - Спасибо!!!
И зачем у вас state int-ом инициирована, у нее всего два состояния, а не 65535. boolean или byte.
Это не ко мне - я просто скопировал: http://arduino.ru/Reference/AttachInterrupt
и тут так же: http://arduino.cc/en/Reference/AttachInterrupt
Похоже просто бездумный перевод.
Надеюсь теперь всё правильно:
Если работает, то вроде да. Из мелких придирок, зачем Vrem объявлена float? Она по вашему коду может когда либо принять значение с десятичным знаком или превысить 255? Старайтесь использовать только типы, необходимые для выполнения программы, кроме экономии памяти это спасет вас от граблей. Попробуйте конструкцию if (Vrem == 25), большие шансы, что она не сработает.
Кварц, даже самый гнилой и самый китайский, не может ошибаться на "примерно 10 сенунд в минуту" или "в минуту почти на 15 секунд".
Я бы, всё-таки, постарался выяснить в чём дело. Там или действительно кварц не на ту частоту, или частота неправильно указана в настройках проекта, или этот кварц вообще отключен какими-нибудь фьюзами.
Ну, или программа написана всё же неправильно - бывает и такое, в конце концов.
У меня был случай с Про Мини. Скетчи на ней выполнялись в десять раз медленнее чем на других ардуинках. Так как в каких-то там фьюзах не понимаю, я просто по совету (извините, не помню кого) с этого форума, просто перезаписал загрузчик. Проблема исчезла. Ардуинка стала работать нормально.
Если работает, то вроде да. Из мелких придирок, зачем Vrem объявлена float? Она по вашему коду может когда либо принять значение с десятичным знаком или превысить 255? Старайтесь использовать только типы, необходимые для выполнения программы, кроме экономии памяти это спасет вас от граблей. Попробуйте конструкцию if (Vrem == 25), большие шансы, что она не сработает.
1 В данном случае Вы правильно подметили, в полной версии моей программы Vrem считает секунды-циклы и это значение пишется на СД карту и его значение будет 0 - 3000.
2 программа будет останавливается если батарея разредилась меньше 3-Вольт и возможно ==3 проскочит и не сработает.
Вы меня не совсем поняли по float, c напряжением на батарее если не принимать никаких мер, придется мирится с вещественным числом. А там где вы оперируете целыми числами при конструкции типа float a=25*4/5 сравнение if(a==20) из за особенности представления вещественного числа в памяти может оказатся ложным. Это надо учитывать
Вы меня не совсем поняли по float, c напряжением на батарее если не принимать никаких мер, придется мирится с вещественным числом. А там где вы оперируете целыми числами при конструкции типа float a=25*4/5 сравнение if(a==20) из за особенности представления вещественного числа в памяти может оказатся ложным. Это надо учитывать
И как это можно исправить?
Так исправлять не надо. Просто помнить, что == на float часто ведет себя не как планировалось. Соответственно >= или <=.
Так исправлять не надо. Просто помнить, что == на float часто ведет себя не как планировалось. Соответственно >= или <=.
Можно , но нет гарантии, что какой-нибудь 10-й разряд после запятой будет равен 0. А 0,5 не равно 0,500000000001
Хотя так, может и получится. Лень проверять.
Действительно, в таком варианте получается.
Не знаю правильно ли я понял проблему. Но мне кажется что if(a==20) нужно заменить на if(a<20). При первом же ближайшем значении все сработает как надо.
Действительно, в таком варианте получается.
А как Вы проверяете?
У меня выходит так (x = 1):
Вот так что то вышло (x = 1) :
Вот так что то вышло (x = 1) :
Действительно все выходит, тоже проверил. Но один раз проскочил по таким граблям, как там сложились условия уже не помню, но пока обнаружил грязь в последнем разряде крови много себе попортил.
По каким причинам может сильно отставать время на модуле с DS3231 при питании от 3В батарейки-таблетки?
По каким причинам может сильно отставать время на модуле с DS3231 при питании от 3В батарейки-таблетки?
Недели две назад у человека отставало из-за дохлой батарейки. И у вас батарейка или аккумулятор на 3,6 должен стоять?
А чем KEYES DS3234 RTC Real Time Clock Module for Arduino лучше?
Кривой андроид и удалить нельзя.
А чем KEYES DS3234 RTC Real Time Clock Module for Arduino лучше?
Лучше чего?
Лучше чего?
3231
Судя по даташиту ничем, шина только другая и ног больше.
Что то у меня сомнение по поводу подтяжки - на модуле стоит подтяжка к 3,3В т.е. после регулятора напряжения тока SOT-23 10pcs XC6206P332MR (662K) 3.3V/0.5A
К 5 Вольтам нужно подтягивать?
Не нужно, все на плате есть. 3,3 вольта - уровень уверенно определяемый как HIGH.
bwn не подскажете какие диоды надо использовать в этой схеме http://arduino.ru/forum/apparatnye-voprosy/initializing-sd-cardinitializ...