Светодиод мигает в цикле в состоянии
Поэтому я объясню, что я хочу получить. Я считываю температуру с DS18B20 и показываю ее на ЖК-дисплее. У меня есть один светодиод на контакте 3, который мигает при чтении температуры и обновлении экрана. У меня есть еще один светодиод на контакте 4, который должен гореть, когда температура больше 25 и меньше 30, и я хочу, чтобы он мигал, когда температура больше 30. То, что я получаю, это мигание, но не как одно мигание каждые 10 мс, но это ждет, пока весь цикл снова начнет мигать. Могу ли я сделать отдельно, чтобы этот светодиод мигал независимо, когда условие истинно? С установленным интервалом, например, 10 мс, который не будет ждать весь цикл.
вот мой пример кода:
#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Устанавливаем I2C-адрес ЖК-дисплея
//LiquidCrystal_I2C lcd (0x27, ПОЛОЖИТЕЛЬНО); // Устанавливаем I2C-адрес ЖК-дисплея
OneWire ds(2);
unsigned long previousMillis = 0;
const long interval = 1000;
int ledState = LOW;
void setup()
{
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
lcd.begin(16,2); // инициализируем ЖК-дисплей
}
void loop()
{
unsigned long currentMillis = millis();
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
Serial.println();
// первый байт ПЗУ указывает, какая микросхема
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // или старый DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // начинаем преобразование, в конце с включенным питанием паразита
delay(850); // может 750 мс хватит, может нет
// здесь мы могли бы выполнить ds.depower(), но об этом позаботится сброс.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Чтение блокнота
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // нам нужно 9 байт
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Преобразование данных в фактическую температуру
// поскольку результатом является 16-битное целое число со знаком, оно должно
// храниться в типе "int16_t", который всегда равен 16 битам
// даже при компиляции на 32-битном процессоре.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9-битное разрешение по умолчанию
if (data[7] == 0x10) {
// "количество оставшихся" дает полное 12-битное разрешение
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// при более низком разрешении младшие биты не определены, поэтому обнулим их
if (cfg == 0x00) raw = raw & ~7; // 9-битное разрешение, 93,75 мс
else if (cfg == 0x20) raw = raw & ~3; // 10-битное разрешение, 187,5 мс
else if (cfg == 0x40) raw = raw & ~1; // 11-битное разрешение, 375 мс
//// по умолчанию разрешение 12 бит, время преобразования 750 мс
}
celsius = (float)raw / 16.0;
digitalWrite(3, HIGH); // включаем светодиод (HIGH - уровень напряжения)
delay(10); // ждем секунду
digitalWrite(3, LOW); // выключаем светодиод, понижая напряжение
lcd.home ();
lcd.print("Reading 1");
lcd.setCursor( 0, 1);
lcd.print("temp:");
lcd.print(celsius);
lcd.print("*C");
if (celsius >= 25 && celsius < 30) {
digitalWrite(4,HIGH);
} else if (celsius >= 30) {
blink1();
} else {
digitalWrite(4,LOW);
}
}
void blink1() {
digitalWrite(4,HIGH);
delay(50);
digitalWrite(4,LOW);
}
@Mordimer Madderdin, 👍-1
1 ответ
Попробуйте вот это:
#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Устанавливаем I2C-адрес ЖК-дисплея
//LiquidCrystal_I2C lcd (0x27, ПОЛОЖИТЕЛЬНО); // Устанавливаем I2C-адрес ЖК-дисплея
OneWire ds(2);
const long interval = 1000; //Интервал, с которым мигает (миллисекунды)
unsigned long previousMillis = 0;
int ledState = LOW;
void setup()
{
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
lcd.begin(16,2); // инициализируем ЖК-дисплей
}
void loop()
{
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
Serial.println();
// первый байт ПЗУ указывает, какая микросхема
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // или старый DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // начинаем преобразование, в конце с включенным питанием паразита
delay(850); // может 750 мс хватит, может нет
// здесь мы могли бы выполнить ds.depower(), но об этом позаботится сброс.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Чтение блокнота
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // нам нужно 9 байт
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Преобразование данных в фактическую температуру
// поскольку результатом является 16-битное целое число со знаком, оно должно
// храниться в типе "int16_t", который всегда равен 16 битам
// даже при компиляции на 32-битном процессоре.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9-битное разрешение по умолчанию
if (data[7] == 0x10) {
// "количество оставшихся" дает полное 12-битное разрешение
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// при более низком разрешении младшие биты не определены, поэтому обнулим их
if (cfg == 0x00) raw = raw & ~7; // 9-битное разрешение, 93,75 мс
else if (cfg == 0x20) raw = raw & ~3; // 10-битное разрешение, 187,5 мс
else if (cfg == 0x40) raw = raw & ~1; // 11-битное разрешение, 375 мс
//// по умолчанию разрешение 12 бит, время преобразования 750 мс
}
celsius = (float)raw / 16.0;
lcd.home ();
lcd.print("Reading 1");
lcd.setCursor( 0, 1);
lcd.print("temp:");
lcd.print(celsius);
lcd.print("*C");
if (celsius >= 25 && celsius < 30) {
digitalWrite(4,HIGH);
} else if (celsius >= 30) {
blink1();
} else {
digitalWrite(4,LOW);
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(3, ledState);
}
}
void blink1() {
digitalWrite(4,HIGH);
delay(50);
digitalWrite(4,LOW);
}
а также обратите внимание, что я выбрал 1000 миллисекунд для интервала (равного 1 секунде), поэтому, если вы хотите 10 мс, как в своем первом сообщении, измените const long interval
на 10
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату