Помогите с кодом
- Войдите на сайт для отправки комментариев
Чт, 01/02/2018 - 23:02
Здравствуйте, помогите пожалуйста , уже 2 недели мучаюсь. Я новичек в Arduino поэтому прошу не пинать меня)
Код бортового компьютера для авто. Код работает, но есть проблемма.
Проблемма заключается в сохранении EEPROM.
Использую строки
EEPROM.get(104, benz_full);
EEPROM.get(200, odometr);
и записываю
EEPROM.put(104, benz_full);
EEPROM.put(200, odometr);
Но после перезапуска Odometr загружается и считает дальше, а benz_full загружается но после получения данных сбрасывает на 0 и начитает считать. Код прилагаю.
#include <LiquidCrystal_I2C.h> #include <EEPROM.h> #include "ecu.h" LiquidCrystal_I2C lcd(0x27, 20, 4); // LiquidCrystal(rs, enable, d4, d5, d6, d7) Ecu ecu; unsigned long time_new, time_old, time_old_gurnal; uint32_t t; int rpm_var, uoz_var, polozh_dross_zaslon, speed_var, inj_time_var, speed_var3, speed_var4, tmp_var, t2, t1; float time, inj_time_full, odometr_add, inj_time_cycle, odometr_add3, odometr_add4, voltage, benz_full_eeprom; bool flagNulSpeed = true; float odometr = 0; float benz_full = 0; float benz_100 = 0; void setup() { Serial.begin(38400); lcd.init(); lcd.backlight(); t = millis(); EEPROM.get(104, benz_full); EEPROM.get(200, odometr); } void loop() { uint32_t new_t; uint16_t diff_t; inj_time_cycle = 0; int rpm_var = ecu.getRpm(); int tmp_var = ecu.getEct(); int voltage = ecu.getBattery(); t = millis(); { Speed(); // получить скорость if (time_old == 0) { time_old = millis(); // выполнится один раз при появлении оборотов } time_new = millis(); // время со старта программы в мс time = (double(time_new - time_old) / 1000.0); // прошло время с последнего расчета скорости, расхода - в сек if (time > 10) { time = 0; } time_old = time_new; // записать новое время для сравнения в следующем цикле if (speed_var > 0) { odometr_add = double((double(speed_var * 1000.0) / 3600.0) * time) / 1000.0; odometr = odometr + odometr_add; //обший пробег в км } } Benz(); // расход и время форсунок if (inj_time_var > 0) { new_t = millis(); diff_t = new_t - t; inj_time_cycle = rpm_var / 120000.0 * 4.0 * (float)diff_t * inj_time_var;//общее время форсунок за поездку inj_time_full = double(double(inj_time_cycle + inj_time_full)) ; //общее время форсунок за поездку (соовсем общее) benz_full = double(double((inj_time_full * 0.005416666666667) / 10.0)); //бензин за поездку benz_100 = benz_full / odometr * 100;//средний расход на 100 км за поездк } EEPROM.put(104, benz_full); EEPROM.put(200, odometr); lcd.setCursor(0, 0); lcd.print(speed_var); // Скорость lcd.print(" km/h"); lcd.setCursor(12, 0); lcd.print(rpm_var); //Обороты lcd.print(" rpm"); lcd.setCursor(0, 1); float cons = ecu.getInstantConsumption(); lcd.print(cons); // л/час lcd.print(" L/h"); lcd.setCursor(12, 1); lcd.print(benz_full); lcd.setCursor(0, 2); float cons1 = ecu.getInstantfFuel(); lcd.print(cons1); lcd.print(" L/100"); lcd.setCursor(12, 2); lcd.print(tmp_var); //Температура lcd.setCursor(0, 3); lcd.print(odometr); // пройденный путь с заводки авто lcd.print(" km"); lcd.setCursor(12, 3); lcd.print(benz_100); // средний расход на 100 км lcd.print(" L"); } void Speed(void) { speed_var = ecu.getVss(); } void Benz(void) { inj_time_var = ecu.getInj(); } void Tmp(void) { tmp_var = ecu.getEct(); } void Rpm(void) { rpm_var = ecu.getRpm(); } void DavlenVpuskKoll(void) { ecu.getMap(); } void IntakeAirTemp(void) { ecu.getIat(); } void Voltage(void) { voltage = ecu.getBattery(); } void Uoz(void) { ecu.getInj(); } void Pdz(void) { ecu.getTps(); }
У вас в коде так и есть - в случае одметра новое значение километража прибавляется с старому, а в случае с benz_full вы прочитанные из ЕПРОМ данные в программе нигде не используете, а вместо этого в строке 66 считаете banz_full с нуля.
ЗЫ На будущее - не создавайте тем с глупыми, ничего не значащими названиями - типа "Помогите новичку" или как у вас. Пишите конкретно - "Не заполняется массив", "Не обновляются данные из епром" и тд
Спасибо, буду исправляться)
если вас правильно понял то код должен быть такой?
мне кажется, вы не вполне понимаете логику своей (?) программы. Я не очень хорошо понимаю, что вообще такое benz_full. но, по-моему, вы его снова считаете неправильно. Во-всяком случае, в этом скетче вы точно также, как и в первом, не используете данные, прочитанные из ЕПРОМ.
Уже голова кругом если честно , вообщем benz_full это количество спаленного топлива за время работы ардуино . Так вот я хочу сделать чтобы , оно при отключении питания сохранялось , а при включении ардуино , продолжала его . Просто как мне кажется , я с full_Benz делаю тоже самое , что и с odometr. Но одометр считается , а бензин нет.
строчки 66-68 попробуйте так переписать
Наверное так не получится мне нудно сохранить в eeprom именно количество топлива , то есть например benz_full = 1.0 при выключении ардуино оно его сохраНила в eeprom , а при включении достало его и начала считать дальше , 1.0 ,1.1 ,1.2 ....
нет, немного не так. Если я правильно понимаю ваши формулы - вот так надо
только комментарии неверные.
benz_add - это бензин не за всю поездку, а только со времени предыдущего расчета, а benz_100 - расход не за поездку, а за все время накопления данных
по-моему, мы это и делаем, что вас смущает?
Скажите для определенности - эти формулы ваши или вы их где-то в инете скопировали вместе с кодом? Вы их понимаете и можете обьяснить, что и как считается в формулах?
Нет формула Benz_full выводит кол-во литров топлива , которое авто спалило с момента включения ардуино. Т.е
inj_time_full - это сумарное время открытых форсунок с момента включения
0.005416666666667 - это производительность форсунки
При выводе формулы на экран показывает кол-во потраченного бензина с момента включения.
Код мой , на него уже месяц потратил , все работает , только с eeprom как-то тяжеловато.
Нужно сохранять benz_full и при включении продолжать его .
ок, но тогда придется ввести переменную benz_full_new
код:
По-моему, сейчас все строго так, как вы хотели.
В начале программы читаете из ЕЕПРОМ общий расход бензина в переменную benz_full , а в конце работы сохраняете новое значение из переменной benz_full_new
Вы гений ,спасибо , вроде разобрался. Завтра напишу результат , сейчас на работу ушел.
Спасибо работает.
Сделал вроде правильно, если понял вас правильно)
Спасибо работает.
Сделал вроде правильно, если понял вас правильно)
в строке 22 ошибка, вот это - неправильно:
benz_full = EEPROM.get(104, benz_full_new);
у метода EEPROM.get() нет возвращаетмого значения, поэтому приравнивать что-либо к нему бессмысленно. правильный код такой:
исправил
теперь осталось сделать условие, при котором оно будет сохнатять в EEPROM данные, насколько знаю EEPROM не любит частой перезаписи.
Общепринятых подхода два:
1) писать в ЕПРОМ, когда данные изменились более чем на определенное значение. Этот вариант совсем несложный, главное - определить разумную точность обновляемых данных. Например, показания одометра можно сохранять раз в километр, что дает вам гарантированный минимальный ресурс ЕЕПРОМ 100 000 км, а на практике в несколько раз больше. Для кол-ва топлива разумно писать данные 1 раз на каждый литр или 0.1 литра - при типичном расходе это даст такой же ресурс, как скилометрами.
2)пытаться определить момент окончания работы программы и писать только при выходе. В этом варианте обычно трудность составляет то, что нужно успеть записать ЕПРОМ, пока не пропало питание. Но так как у вас блок будет стоять на авто, где есть акамулятор, возможно этот вариант можно сделать проще.
Первый вариант проще, второй - эффективнее.
ЗЫ - еще раз внимательно посмотрел формулы - мне все же кажется, что кол-во и расход бензина в строках 62 -68 считается неверно. Проверьте еще раз. Например, точно ли разницу во времени надо считать по переменной t ? - это получается не время с прошлого цикла, а какое-то случайное значение