Нужна помощь по калибровке аналогового датчика
- Войдите на сайт для отправки комментариев
Вс, 11/03/2018 - 17:36
Есть такой вариант калибровки .
/*
Пока нажата кнопка, в программе будет работать только функция калибровки.
На основе данных от датчика, считанных за это время, будут определены новый максимум и минимум.
Это вариация примера «Калибровка».
Цепь:
* фоторезистор подключен к 0-ому аналоговому и 5-вольтовому контактам
* 10000-омовый резистор подключен к «земле» и 0-ому аналоговому контакту
* светодиод через 220-омовый резистор подключен к 9-ому цифровому контакту, а также к «земле»
* кнопка подключена ко 2-ому цифровому и 5-вольтовому контактам
* 10000-омовый резистор подключен ко 2-ому цифровому контакту и «земле»
*/
// это константы, т.е. значения, которые не изменятся:
const int sensorPin = A0; // контакт, к которому подключен датчик
const int ledPin = 9; // контакт, к которому подключен светодиод
const int indicatorLedPin = 13; // контакт, к которому подключен встроенный светодиод
const int buttonPin = 2; // контакт, к которому подключена кнопка
// это переменные, т.е. значения, которые изменятся:
int sensorMin = 1023; // минимальное значение от датчика
int sensorMax = 0; // максимальное значение от датчика
int sensorValue = 0; // значение, считанное от датчика
void setup() {
// задаем контакты светодиодов как выходные,
// а контакт кнопки – как входной
pinMode(indicatorLedPin, OUTPUT);
pinMode (ledPin, OUTPUT);
pinMode (buttonPin, INPUT);
}
void loop() {
// пока нажата кнопка, берем данные для калибровки:
while (digitalRead(buttonPin) == HIGH) {
calibrate();
}
// даем сигнал о начале калибровочного периода:
digitalWrite(indicatorLedPin, LOW);
// считываем данные от датчика:
sensorValue = analogRead(sensorPin);
// применяем калибровку к считанным данным:
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
// задаем лимит, если во время калибровки данные от датчика
// вышли за пределы нужного диапазона:
sensorValue = constrain(sensorValue, 0, 255);
// меняем яркость светодиода на основе откалиброванных значений:
analogWrite(ledPin, sensorValue);
}
void calibrate() {
// включаем светодиод, оповещая о том, что калибровка завершена:
digitalWrite(indicatorLedPin, HIGH);
// считываем данные от датчика:
sensorValue = analogRead(sensorPin);
// записываем максимальное значение:
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// записываем минимальное значение:
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}
Но при выключении питания настройки калибровки сбрасываются. Прошу помощи в добавлении таких функций:
1. При входе в режим калибровки данные из EEPROM стираются и устанавливаются на дефолтные 0,1023.
2. При выходе из режима калибровки новые данные записываются в EEPROM и далее считываются с EEPROM
пи.си. Я очень начинающий ардуинщик, поэтому прошу не использовать сильно умные слова. :0)
п. 1 у Вас явно лишний.
Посмотрите библу EEPROM, вернее, демку, прилагаемую к ней - там есть и запись и считывание.
При нажатии кнопки и входе в режим калибровки, взводите флаг о нужности записи в память.
При отпущенной кнопке проверяете этот флаг, делаете запись и опрокидываете флаг (флаг нужен, что бы 100500 раз не записывалось).
ЗЫ. Вот готовые функции для считывания и записи целочисленного значения в/из EEPROM
/* Read integer value */ int EEPROM_int_read(int addr) { byte raw[2]; for (byte i = 0; i < 2; i++) { raw[i] = EEPROM.read(addr + i); } int &num = (int&)raw; return num; } /* Write integer value */ void EEPROM_int_write(int addr, int num) { byte raw[2]; (int&)raw = num; for (byte i = 0; i < 2; i++) { EEPROM.write(addr + i, raw[i]); } }мне нужно записать и считать число,например, 1023. Оно займет две ячейки памяти. Как корректно это сделать?
https://www.arduino.cc/en/Reference/EEPROMPut
вообщем сейчас работает в таком виде
покритикуйте, если шо.
С делением и умножением на 4 - полный бред.
Записывайте сразу полное число (функции выше я давал) -
Пишем значение value по адресу 0
EEPROM_int_write(0, value);
и читайте из адреса 0
value = EEPROM_int_read(0);
или, как предлагали дальше, функции EEPROM.put() и EEPROM.get
EEPROM.put(0, value);
и
value = EEPROM.get(0);
Учитывая, что тип int занимает 2 байта, то следующий адрес будет 2, затем 4 и.т.д.
можешь скетч выше поправить как надо? А то мне пока это всё как ядерная физика...
так нормально?
#include <EEPROM.h> int a = 0; // переменая для вывода в монитор int value; // переменая для вывода в монитор bool prevState = LOW; // это константы, т.е. значения, которые не изменятся: const int sensorPin = A0; // контакт, к которому подключен датчик const int ledPin = 9; // контакт ШИМ, к которому подключен светодиод const int indicatorLedPin = 13; // контакт, к которому подключен встроенный светодиод const int buttonPin = 2; // контакт, к которому подключена кнопка // это переменные, т.е. значения, которые изменятся: int sensorMin = 1023; int sensorMax = 0; int sensorValue = 0; // значение, считанное от датчика int sensorValue1 = 0; // значение, считанное от датчика для монитора void setup() { Serial.begin (9600); pinMode(indicatorLedPin, OUTPUT); //светодиод на борту ардуины pinMode (ledPin, OUTPUT); //светодиод на выходе ШИМ pinMode (buttonPin, INPUT); //кнопка EEPROM.get( 0, sensorMin ); EEPROM.get( 2, sensorMax ); } void loop() { Serial.print(a);//на монитор Serial.print("\t");//на монитор Serial.print(value);//на монитор value = EEPROM.read(a); //на монитор a = a + 1; if (a == 5) a = 0; delay (1);//для задержки в мониторе. потом нужно удалить Serial.print (" /in "); Serial.print (sensorValue1); Serial.print (" /min "); Serial.print (sensorMin); Serial.print (" /max "); Serial.println (sensorMax); // пока нажата кнопка, берем данные для калибровки: while (digitalRead(buttonPin) == HIGH) { if (prevState == LOW) { sensorMax = 0; //сбрасываем переменную sensorMin = 1023; //сбрасываем переменную prevState = HIGH; //выставляем что бы повторно в цикле не обнулять } calibrate(); } digitalWrite(indicatorLedPin, LOW); // даем сигнал о начале калибровочного периода: sensorValue = analogRead(sensorPin);// считываем данные от датчика: sensorValue1 = analogRead(sensorPin);// считываем данные от датчика: sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);// применяем калибровку к считанным данным: sensorValue = constrain(sensorValue, 0, 255); // задаем лимит, если во время калибровки данные от датчика вышли за пределы нужного диапазона: analogWrite(ledPin, sensorValue);// меняем яркость светодиода на основе откалиброванных значений: prevState = LOW; } void calibrate() { Serial.print (" in "); Serial.print (sensorValue1); Serial.print (" /min "); Serial.print (sensorMin); Serial.print (" /max "); Serial.println (sensorMax); digitalWrite(indicatorLedPin, HIGH);// включаем светодиод, оповещая о том, что калибровка завершена: sensorValue = analogRead(sensorPin);// считываем данные от датчика: sensorValue1 = analogRead(sensorPin);// считываем данные от датчика: // записываем максимальное значение: if (sensorValue > sensorMax) { sensorMax = sensorValue; } // записываем минимальное значение: if (sensorValue < sensorMin) { sensorMin = sensorValue; } if (prevState == HIGH) { //тут записываем новые данные калибровки в память // теперь одна простая функция, где первый аргумент – это адрес, а второй – объект: EEPROM.put(0, sensorMin); EEPROM.put(2, sensorMax); } }AndreiPol. Похоже надо начинать сначала. А вначале у нас было
СЛОВОописание как правильно должно работать ваше устройство.а что сейчас не так? В железе проверил, работает корректно.
Мда. Попробуйте еще. Похоже я отвлекся , когда вы проверяли. Может сейчас замечу.
ПС: А пока вы это повторяете опишите, какие действия вы делаете для калибровки.
это сокращённая версия без вывода на монитор
#include <EEPROM.h> bool prevState = LOW; // это константы, т.е. значения, которые не изменятся: const int sensorPin = A0; // контакт, к которому подключен датчик const int ledPin = 9; // контакт ШИМ, к которому подключен светодиод const int indicatorLedPin = 13; // контакт, к которому подключен встроенный светодиод const int buttonPin = 2; // контакт, к которому подключена кнопка // это переменные, т.е. значения, которые изменятся: int sensorMin = 0; int sensorMax = 0; int sensorValue = 0; // значение, считанное от датчика void setup() { pinMode(indicatorLedPin, OUTPUT); //светодиод на борту ардуины pinMode (ledPin, OUTPUT); //светодиод на выходе ШИМ pinMode (buttonPin, INPUT); //кнопка EEPROM.get( 0, sensorMin ); EEPROM.get( 2, sensorMax ); } void loop() { // пока нажата кнопка, берем данные для калибровки: while (digitalRead(buttonPin) == HIGH) { if (prevState == LOW) { sensorMax = 0; //сбрасываем переменную sensorMin = 1023; //сбрасываем переменную prevState = HIGH; //выставляем что бы повторно в цикле не обнулять } calibrate(); } digitalWrite(indicatorLedPin, LOW); // даем сигнал о начале калибровочного периода: sensorValue = analogRead(sensorPin);// считываем данные от датчика: sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);// применяем калибровку к считанным данным: sensorValue = constrain(sensorValue, 0, 255); // задаем лимит, если во время калибровки данные от датчика вышли за пределы нужного диапазона: analogWrite(ledPin, sensorValue);// меняем яркость светодиода на основе откалиброванных значений: prevState = LOW; } void calibrate() { digitalWrite(indicatorLedPin, HIGH);// включаем светодиод, оповещая о том, что калибровка завершена: sensorValue = analogRead(sensorPin);// считываем данные от датчика: // записываем максимальное значение: if (sensorValue > sensorMax) { sensorMax = sensorValue; } // записываем минимальное значение: if (sensorValue < sensorMin) { sensorMin = sensorValue; } if (prevState == HIGH) { // тут записываем новые данные калибровки в память // теперь одна простая функция, где первый аргумент – это адрес, а второй – объект: EEPROM.put(0, sensorMin); EEPROM.put(2, sensorMax); } }Объсняю ... Берем устройство . Подключаем к эталону на котором максимум и нажимаем кнопку максимум. Потом подключаем к эталону на котором минимум и нажимаем кнопку минимум. Все устройство откалибровано. И нефиг всяким шаманам стручать в барабаны и бегать по кругу. Это не калибровка.
ну можно и так...
нужно так. Но у вас ошибка уже на уровне описания технического задания. Так что переписывайте все .
не я ж эту калибровку придумал. Взял готовое из примеров и чуток допилил...
не я ж эту калибровку придумал. Взял готовое из примеров и чуток допилил...
Вы всерьез полагаете, что ерунду можете придумать только Вы и больше никто?