|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 2:26 pm
Две променливи да се записват в EEPROM na arduino
| Автор |
Съобщение |
|
koko76bj
Ранг: Минаващ
Регистриран на: Вто Юни 27, 2017 8:03 am Мнения: 24 Местоположение: Варна
|
 Две променливи да се записват в EEPROM na arduino
Здравейте започнах да пиша код за терморегулатор с настройка на две различни температури от енкодер,но не знам как да направя записа и четенето на тези две различни променливи в EEPROM.Гледах и четох как се работи със запис и четене в eeprom, но не разбрах как става когато са повече от една променливите.Ако може някой да помогне как да реша тази задача много ще съм мъ благодарен. Това ми е кода който написах до сега и изобщо все още не е довършен.  |  |  |  | Код: #include <OneWire.h> #include <DS18B20.h> #include <EEPROM.h> #include <Wire.h> #include <JC_Button.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
#define ONE_WIRE_BUS 2 byte sensorAddress[8] = {0x28, 0x9A, 0x47, 0xE1, 0x06, 0x00, 0x00, 0xCF}; OneWire oneWire(ONE_WIRE_BUS); DS18B20 sensors(&oneWire); #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif
#define encoder_clk 2 //Arduino UNO (nano) pin 10 #define encoder_dt 3 //Arduino UNO (nano) pin 11 #define Fan_relay1 0 //Arduino UNO (nano) pin A0 #define Fan_relay2 1 #define temperatureSetupMode 12 //Rotary encoder SWITCH (SW) - button (menu entry)
volatile byte A = 0; volatile byte B = 0; volatile float encoder = 0; volatile byte encoder_read = 0; volatile uint8_t PORTB_default = 0xFF;
#define DEBOUNCE_MS 20 //debounce 20 ms #define REPEAT_FIRST 1000 //ms required before repeating on long press #define REPEAT_INCR 200 //repeat interval for long press #define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor. #define INVERT true #define LONG_PRESS 2000 //long press to menu entry (2 seconds)
Button btn_setup(temperatureSetupMode, PULLUP, INVERT, DEBOUNCE_MS);
float Temp_regulation1; float Temp_regulation2; float Temp; //int relay_state = 0;
enum STATES { Init, Idle, MEASURE_REGULATION, //measuring and temperature regulation //MEASURE_REGULATION T2 SETUP, // setup }; STATES state;
void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); sensors.begin(12); sensors.request(sensorAddress);
pinMode(Fan_relay1,OUTPUT); pinMode(Fan_relay2,OUTPUT); pinMode(encoder_clk,INPUT_PULLUP); pinMode(encoder_dt,INPUT_PULLUP);
state = MEASURE_REGULATION ; read_EEPROM(Temp_regulation1); read_EEPROM(Temp_regulation2); encoder = Temp_regulation*10; //PIN CHANGE INTERRUPT on encoder_clk and encoder_dt pins PCICR |=(1<<PCIE0); PCMSK0 |= (1<<PCINT2) | (1<<PCINT3); sei(); )
void loop() { state_change(); input_check(); temp_measuring(); }
//PIN change (encoder pins) interrupt routine ISR(PCINT0_vect) { uint8_t PORTB_change; PORTB_change = PINB ^ PORTB_default; PORTB_default = PINB;
if(PORTB_change & (1 << PINB2))//change on PCINT2 { encoder_read = PINB & 0xC; if(encoder_read == B00001100 && A) { encoder--; B = 0; A = 0; } else if (encoder_read == B00000100) B = 1; }
if(PORTB_change & (1 << PINB3))//change on PCINT3 { encoder_read = PINB & 0xC; if (encoder_read == B00001100 && B) { encoder++; B = 0; A = 0; } else if (encoder_read == B00001000) A = 1; } }
void state_change() { switch (state) { case Init:
digitalWrite(Fan_relay1,LOW); digitalWrite(Fan_relay2,LOW); state = Idle;
case Idle: break;
case MEASURE_REGULATION: display.clearDisplay(); display.setTextSize(3); display.setTextColor(WHITE); display.setCursor(30,20); display.println(sensors.getTempCByIndex(0)); display.display(); delay(2000); display.clearDisplay();
void input_check() { btn_setup.read(); //read rotary encoder switch (SW pin)
switch (state) { case MEASURE_REGULATION: regulation(); if (btn_setup.pressedFor(LONG_PRESS)) //long press encoder switch to enter setup { display.clearDisplay(; state = SETUP; } break; case SETUP: digitalWrite(Fan_relay1,LOW); //relay1 OFF digitalWrite(Fan_relay2,LOW); Temp_regulation = encoder / 10; if (Temp_regulation > 55.0) { Temp_regulation = 5.0; } if (Temp_regulation < 5.0) { Temp_regulation = 55.0; } if (btn_setup.wasPressed()) {
display.clearDisplay(); write_EEPROM(0, Temp_regulation); state = MEASURE_REGULATION; } break; } }
void temp_measuring() { if (sensors.available()) { Temp = sensors.readTemperature(sensorAddress); sensors.request(sensorAddress); } }
void write_EEPROM(int address, float Temp_regulation) { byte* p = (byte*)(void*)&Temp_regulation; for (int i = 0; i < sizeof(Temp_regulation); i++) EEPROM.write(address++, *p++);
display.setCursor(30,20); display.println("Saved!!!"); delay(1000); display.clearDisplay(); }
float read_EEPROM(int address) { byte* p = (byte*)(void*)& Temp_regulation; for (int i = 0; i < sizeof(Temp_regulation); i++) *p++ = EEPROM.read(address++); return Temp_regulation; if (isnan(Temp_regulation)) { Temp_regulation=22.2; } }
void regulation() { if (Temp <= Temp_regulation) { digitalWrite(Fan_relay1,HIGH); //relay1 ON } else if (Temp >= Temp_regulation) { digitalWrite(Fan_relay1,LOW); //relay1 OFF } } |  |  |  |  |
|
| Чет Дек 10, 2020 4:52 pm |
|
 |
|
Bai Ui
Ранг: Форумен бог
Регистриран на: Вто Ное 06, 2018 5:18 pm Мнения: 1750
|
 Re: Две променливи да се записват в EEPROM na arduino
Имай в предвид че епрома има ограничен брой записи (износва се), може да четеш колкото си искаш от него но ако направиш 100 хиляди записа (примерно) ще започне да записва грешки. Просто споменавам, да не се чудиш после къде е грешката в кода.
_________________ “Intelligence is the ability to adapt to change.” Stephen Hawking
|
| Чет Дек 10, 2020 6:40 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: Две променливи да се записват в EEPROM na arduino
ско ще правиш много записи мести зоната за запис така ще увеличиш броя записи.
|
| Чет Дек 10, 2020 7:11 pm |
|
 |
|
koko76bj
Ранг: Минаващ
Регистриран на: Вто Юни 27, 2017 8:03 am Мнения: 24 Местоположение: Варна
|
 Re: Две променливи да се записват в EEPROM na arduino
Да това го знам. Записа може би на година веднъж ще се сменя. Няма да има постоянно променящи се записи.
|
| Чет Дек 10, 2020 7:21 pm |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
 Re: Две променливи да се записват в EEPROM na arduino
Ей, никой не му подсказва на човека.. Та, просто трябва да четеш и пишеш от/в друг адрес за да имаш множество променливи. Може пък да ползваш структура, която да ти обедини няколко данни, които ще записваш в еепром-а. Като гледам как ползваш read_EEPROM, ме навежда на мисълта, че грам идея нямаш какво правиш. Като параметър се иска от теб да подадеш адрес от който да се чете. Примерно 0. Гледам че записваш float в еепрома, значи ти трябва колко е голям флоут-а в байтове. https://www.arduino.cc/en/pmwiki.php?n=Reference/Float - 32бита или 4 байта. Адреса за втората ти променлива ще трябва да е +4 като минимум. read_EEPROM хич не ми харесва. Появява се някаква глобална променлива Temp_regulation, дето изобщо не я виждам къде е дефинирана. Дори не стоплям защо я има. Код след ретърн не се слага.. по очевадни причини. Та, без да се засягаш, но ще трябва да започнеш от А-Б на C-то, иначе рискуваш подобни теми да стоят без отговор.
|
| Нед Дек 13, 2020 8:15 pm |
|
 |
|
koko76bj
Ранг: Минаващ
Регистриран на: Вто Юни 27, 2017 8:03 am Мнения: 24 Местоположение: Варна
|
 Re: Две променливи да се записват в EEPROM na arduino
Temp_regulation се дефинира в началото, но когато стигнах до момента да се записват и четат две променливи просто спрях защото не знах как да продължа. И се обърках за помощ към всички по-знащи и можещи във форума от мен. Аз тепърва се уча и доста чета, гледам и пробвам, но все пак се е друго някой да ти покаже или обясни на прост език кое как да стане.
|
| Нед Дек 13, 2020 8:46 pm |
|
 |
|
ike
Ранг: Форумен бог
Регистриран на: Пет Фев 04, 2005 9:59 pm Мнения: 6019 Местоположение: София
|
 Re: Две променливи да се записват в EEPROM na arduino
koko76bj ардуиното се ползва, когато намериш готов проект и просто да го "налееш" без да го бараш или когато искаш да се учиш. 1. Ако искаш да се учиш - първо започваш от по-простото - например само четене и само запис в EEPROM. В момента кода който си го пуснал върши 1001 неща едновремено и ако дори едно от тях се обърка цялата програма отива подягодите и нищо няма да стане. 2. При микроконтролерите плаваща запетая не се ползва. Дори и тези микроконтролери, които имат хардуерен модул за плаваща запетая, кода за плаващата запетая е само в 1-2 функции оградени с много !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!. Виж дали не можеш да използваш 8 битова променлива за температури от -128 до +127 градуса. 3. Личи си че си преписвал от 2 отделни кода. Унифицирай си променливите. Моя съвет е да използваш <stdint.h> https://pubs.opengroup.org/onlinepubs/9 ... int.h.html и всичките ти променливи да са от тип int8_t, int16_t, int32_t, uint8_t, uint16_t и uint32_t. 4. Въпроса ти е как една 32 битова променлива да я представя като 4 отделни 8 битови променливи. Това става като ожениш променливата. Може също така да ползваш и EEPROM.put и EEPROM.get и там дирекнтно да сложиш float T. Ако искаш да запишеш последователно 3 отделни float(32 бита) променливи в EEPROM, тогава първата я четеш и записваш от адрес 0, втората от адрес 4, третата от адрес 8. Или по-универсално VariableNumber*sizeof(float), като VariableNumber номера на променливата например 0 или 1 или 2 или 5 или 10.
_________________ Warriors of the Night, ASSEMBLER!!!
|
| Вто Дек 15, 2020 8:22 pm |
|
 |
|
Desert Leo
Ранг: Форумен бог
Регистриран на: Чет Фев 10, 2005 3:25 pm Мнения: 5677 Местоположение: София
|
 Re: Две променливи да се записват в EEPROM na arduino
Ееее, ike, тук прекаляваш.
|
| Сря Дек 16, 2020 11:07 am |
|
 |
|
toxigen
Ранг: Минаващ
Регистриран на: Чет Май 17, 2018 3:38 pm Мнения: 68 Местоположение: София
|
 Re: Две променливи да се записват в EEPROM na arduino
Да кажем, че се избягва 
|
| Пет Дек 18, 2020 10:09 am |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
 Re: Две променливи да се записват в EEPROM na arduino
Да кажем, че зависи от задачата и от микроконтролера, а не от предубежденията натрупани до 18 годишна възраст.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Пет Дек 18, 2020 11:59 am |
|
 |
|
Desert Leo
Ранг: Форумен бог
Регистриран на: Чет Фев 10, 2005 3:25 pm Мнения: 5677 Местоположение: София
|
 Re: Две променливи да се записват в EEPROM na arduino
Така си е. Ако трябват сметки с тригонометрични функции, няма как без float. Но, ако трябва да се предават данни (по радио, GPRS, SMS, ...) е по-добре да е като integer (където е възможно). Ако измервам температура с резолюция до десета от градуса в диапазона -40...+125, signed integer представянето е -400...+1250, което е 2 байта, а като float е четири байта. А цепенето на signed int16 на два unsigned int8 става и с прости сметки, ако няма вградени функции за целта.
|
| Пет Дек 18, 2020 1:12 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
 Re: Две променливи да се записват в EEPROM na arduino
С позволението на автора на темата... понеже заораваме в офтопик... Лео, Понеже зад причините, които посочваш в примерите ти стои оптимизационна цел. В случая оптимизиране на размер и време за предаване на данни(вероятно това ти е на дневен ред), да сложа и моите 2 ст - оптимизационната цел може и да е друга. Само като пример, не че младежа с х'Ардуино-то има точно този случай, а защото сме в офтопик вече. На float аз предпочитам да гледам като на стандартизиран интерфейс(IEEE-754) отколкото на супер магическо средство за точни и прецизни сметки. Защото сметките с float не предлагат кой знае какво повече като точност и прецизност от оптимизирани според случая целочислени сметки(ако оптимизационната цел е прецизност или точност а не размер и скорост). Дори бих казал за човек с недостатъчно опит или с розовите очила на "всичкознаещия бат'Коко", float крие много изненади. Но когато софтуера, който пишеш трябва да вади данни на някой от своите интерфейси(нямам предвид само хардуерни интерфейси) и когато твоето парче код се вгражда в цялата система от друг и в друго време, в доста случаи е по-добре на този интерфейс твоето парче софтуер да вади float отколкото някакъв оптимизиран формат за който трябва да предоставиш и спецификация към него. И като сложиш това че отдавна има ембедед софтуер(който върви на микроконтролер) и който съдържа няколко стотин интерфейса някъде по пътя на стотината dataflow, които на всичкото отгоре и се променят минимум 1-2 пъти в месеца и се преизползват в различни проекти. Тогава използването на float и дори на double може да се отплати многократно, като дори цената под формата на повече памет и "по-мощен" микроконтролер да не може да наклони везните към "избягване на float". Ако скалираме примера надолу към системи с ограничени ресурси където оптимизационната цел по-често е баланс с количество памет и скорост, смея да твърдя, че дори и тогава, докато данните не са излезли от твоя домейн и от някой от интерфейсите на твоя домейн, може да си правиш каквито намериш за добре оптимизации и да си измисляш каквито намериш за добре целочислени представяния на данните. Особено, когато ти си единствения тъкач на стана - и на софтуера и на хардуера. Т.е. няма нужда да описваш подробно какво правиш за някой друг след теб. Но когато трябва данни с определена прецизност да се изведат "навън" извън твоя домейн(област в която ти работиш и ти колиш и бесиш демек) може да се окаже че е по-добре данните да излязат в стандартизиран и общоприет формат, какъвто е float IEEE-754. Та не се знае какъв път ще се наложи да извърви младежа, който тръгва сега от PIC или AVR. И какви задачи ще срещне в бъдеще. Не набивайте в главата на всеки, едни и същи неща, каквито са ви набити и на вас в главите. Не случайно хората ползват float и при микроконтролери. Не е защото не знаят как да оптимизират сметките за целочислено представяне. Оптимизационната цел и критерии може да са други. А тригонометрични сметки може и да се оптимизират с таблици с оптимизирани целочислени константи и пак да няма нужда от float, ако това е оптимизационната цел.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Пет Дек 18, 2020 3:29 pm |
|
 |
|
Desert Leo
Ранг: Форумен бог
Регистриран на: Чет Фев 10, 2005 3:25 pm Мнения: 5677 Местоположение: София
|
 Re: Две променливи да се записват в EEPROM na arduino
Що да е офтопик? Точно по темата коментараме.
Последна промяна Desert Leo на Пет Дек 18, 2020 5:07 pm, променена общо 1 път
|
| Пет Дек 18, 2020 4:27 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
 Re: Две променливи да се записват в EEPROM na arduino
Всяко нещо си има плюсове и недостатъци... Колко са големи зависи от платформата. На RISC базирани процесори без FPU разликата между int и float е огромна. Говорим за порядъци и то порядъци както в използвана памет, така и бързодействие. Казвам го като човек, който пише и на асемблер и на С++ и знам как се третира и едното и другото от различни компилатори. Не се подвеждайте от размера. Проблемът не е размерът. Проблемът е, че се налага използването на ABI (application binary interface). Примерно има някаква аритметика с 10-на променливи. Ако тази аритметика е целочислена, всички променливи отиват в регистри, всички операции се кодират с най-много една инструкция (често и по-малко). Но ако тази аритметика е с плаваща запетая всичко отива по дяволите. Променливите отиват в стека, щото за всяка операция се вика функция и трябва да се спази ABI-то. Картинката става доста по-различна. Но независимо дали е грозно или не, когато козата иска пръч няма какво да говорим. Ако има величини, които не могат да се вместят в целочисления диапазон, то тогава е ясно. Така че диапазонът на величината е решаващ. Не оптимизациите. Но в случая величината е температура. Няма нужда от никакви плаващи или неплаващи запетаи. Достатъчно е мерната единица вместо 1 градус да се сложи на една десета, една стотна или ако щете 1 милиградус и всички си става целочислено.
|
| Пет Дек 18, 2020 4:49 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
 Re: Две променливи да се записват в EEPROM na arduino
Доколкото записа в EEPROM може да се разглежда също като входно/изходна точка в която имаме интерфейс(независимо дали го разпознаваме като такъв или не) тогава да, не сме офтопик. Но понеже въпроса на автора на темата е в категорията "Как?" а не в категорията "Защо?" сме леко в офтопик. Миро, Те променливите дали ще са в стека или в регистри е пак важно ако оптимизираме за скорост. Т.е. пак оптимизационната цел е определяща  А ако вътре в дадено парче софтуер въртиш целочислени сметки, но се наложи да ги подадеш "навън", на следващия като float. Предполагам няма нужда да обяснявам защо може да е по-бързо всички сметки и вътре в твоето "парче софтуер" да минат на float.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Пет Дек 18, 2020 5:04 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 5 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|