Показания датчика
Пусть теперь первая плата Ардуино считывает значение датчика освещенности на основе фоторезистора и передает эти показания в UART. Вторая плата будет принимать данные, и менять яркость светодиода согласно полученному значению.
Для этого примера к ведущей плате подключим фоторезистор по схеме из нашего урока. А к ведомой плате — светодиод к любому контакту с ШИМ выходом (для Arduino Uno это контакты: 3,5,6,9,10,11). ШИМ выход нам понадобится чтобы плавно менять яркость светодиода функцией analogWrite.
Программа ведущего
byte photoPin = A0;
void setup() {
Serial.begin(9600);
pinMode(photoPin, INPUT);
}
void loop() {
int val = analogRead(photoPin);
val = val*255/1023.0;
Serial.write(val);
delay(100);
}
В этой программе мы считываем значение АЦП, к которому подключен фоторезистор, с помощью функции analogRead. Вот только проблема в том, что в UART мы можем передать только один байт, а analogWrite возвращает нам число от 0 до 1023. Чтобы обойти эту неприятность, просто нормируем большое число в диапазон от 0 до 255. Делается это формулой:
val = val*255/1023.0;
Программа ведомого
byte ledPin = 3;
void setup() {
Serial.begin(9600);
pinMode( ledPin, OUTPUT );
}
void loop() {
if( Serial.available() ){
byte v = Serial.read();
// передаем полученное из UART значение в функцию analogWrite
analogWrite( ledPin, v);
}
}
Загружаем программы на контроллеры и подаем питание. Для проверки закрываем фоторезистор рукой и наблюдаем за поведением светодиода, он должен менять яркость.
Как уже было замечено, в этой программе нам пришлось огрубить показания датчика, иначе они не влазили в UART. Эта проблема решается разложением числа на байты и последовательной передачей этих байт в UART (или любой другой последовательный интерфейс). Например, так:
int val = analogRead(photoPin);
Serial.write(val & 0xFF); // передаем младший байт числа val
Serial.write((val>>8) & 0xFF); // передаем старший байт числа val
В программе ведомого, соответственно, нужно будет поймать эти два байта и склеить, например, так:
if( Serial.available()>1 ){
byte v1 = Serial.read();
byte v2 = Serial.read();
int v = v1 | (v2<<8);
}
Но это не тема нашего урока. Лучше попробуем передавать данные в оба направления!
Добрый день!
А как поступить с отрицательными числами?
Точно так же. Передается все равно байт, а уж -128..127 или 0..255 это вам решать на приемнике. Просто создаете переменную нужного типа и в нее записываете значение из UART.
Почитайте про отрицательные числа в двоичном коде у ВМ
Сразу станет понятно что как передавать
https://ru.wikipedia.org/wiki/%D0%94%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4