DominatorBLR:Какие есть ещё способы замера скорости вращения?
датчик отражения и наклейка с белыми и черными секторами.
DominatorBLR:Какие есть ещё способы замера скорости вращения?
датчик отражения и наклейка с белыми и черными секторами.
DominatorBLR:Какие есть ещё способы замера скорости вращения?
как вариант - сельсины ... но как это с ардуиной подружить - надо почитать
офлайн
DominatorBLR
Senior Member
|
|
4611 |
15 лет на сайте Город:
|
Drosha:как вариант - сельсины ... но как это с ардуиной подружить - надо почитать
это будет дорого и сложно
SIO:DominatorBLR:Какие есть ещё способы замера скорости вращения?
датчик отражения и наклейка с белыми и черными секторами.
как вариант, на китае датчики TCRT5000 до доллара. Но на колесе придется наносить полоски, желательно белого цвета, а это значит что колеса должны быть чистые, грязь может привести к погрешности. С другой стороны не так часто в дождь и по грязи катается ребенок, но не исключено. Наверное два датчика закажу сначала эти, а потом в процессе будет видно, понадобиться улучшение данного узла или нет.
DominatorBLR:а это значит что колеса должны быть чистые,
Щетку или ворс прикрутить чтобы полоски протирал от пыли.
офлайн
volkenturbo
Senior Member
|
|
1644 |
16 лет на сайте Город:
|
Добрый день. Сделали вот такой скетч. Суть: выводятся на экран tft данные с датчика температуры. Жму кнопку- экран переключается на обычную надпись "loading.". Но почему-то она постоянно моргает. Может кто нибудь подсказать почему? С отображением температуры всё ок.
// Подключение ТФТ
#define TFT_CS 10
#define TFT_RST 8
#define TFT_DC 9
#define TFT_SCLK 13
#define TFT_MOSI 11
// Параметры датчика DS18B
// Устанавливаем пин 3 на DS18B20
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
float tempMin = 999;
float tempMax = 0;
int barra = 0;
int regim = 0;
int knopka = 2;
int flag = 0;
char conta = 0;
DallasTemperature sensors(&oneWire);
DeviceAddress sensor1;
//Инициализируем дисплей
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void setup() {
pinMode(knopka, INPUT);
Serial.begin(9600);
sensors.begin();
tft.initR(INITR_BLACKTAB); // You will need to do this in every sketch
}
void loop()
{
if (digitalRead(knopka) == HIGH && flag == 0) {
delay(300);
regim = ++regim;
if (regim>1) regim=0;
}
if (digitalRead(knopka) == LOW && flag == 1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ...
{
delay(100);
flag = 0; //обнуляем переменную "knopka"
}
switch (regim) {
case 0:
{
//tft print function!
tft.setTextColor(ST7735_YELLOW);
tft.setRotation(3);
tft.setTextSize(2);
tft.setCursor(35, 10);
tft.println(" TEMP = C");
tft.setTextSize(1);
tft.setCursor(131, 10);
tft.println("O");
termo();
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(0);
tft.setCursor(19, 59);
tft.print("50");
tft.setTextSize(0);
tft.setCursor(19, 106);
tft.print("0");
tft.setTextSize(0);
tft.setCursor(19, 7);
tft.print("100");
tft.setTextSize(0);
tft.setCursor(19, 82);
tft.print("25");
tft.setTextSize(0);
tft.setCursor(19, 32);
tft.print("75");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(2);
tft.setCursor(10, 40);
tft.print(" CUR");
tft.setTextSize(2);
tft.setCursor(20, 65);
tft.print(" MIN");
tft.setTextSize(2);
tft.setCursor(20, 90);
tft.print(" MAX");
// Информация датчика темп.
if (sensors.getAddress(sensor1, 0))
{
sensors.requestTemperatures();
float tempC = sensors.getTempC(sensor1);
// Atualiza temperaturas minima e maxima
if (tempC < tempMin)
{
tempMin = tempC;
}
if (tempC > tempMax)
{
tempMax = tempC;
}
barra = (int)tempC;
// Отображаем на ТФТ
tft.setTextColor(ST7735_RED);
apaga_linha(100, 40);
tft.setTextSize(2);
tft.setCursor(100, 40);
tft.println(tempC, 1);
//tft.print("C");
tft.setTextColor(ST7735_GREEN);
apaga_linha(100, 65);
tft.setCursor(100, 65);
tft.println(tempMin, 1);
tft.setTextColor(ST7735_YELLOW);
apaga_linha(100, 90);
tft.setCursor(100, 90);
tft.println(tempMax, 1);
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(1);
apaga_linha(99, 104);
tft.setCursor(45, 110);
tft.print(" SENSOR OK ");
if (tempMin > 50)
tempMin = 999;
tft.fillRect(5, 12, 7, 99, ST7735_RED);
tft.fillRect(5, 12, 7, 100 - barra, ST7735_BLACK);
conta++;
if (conta == 1)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" |");
}
if (conta == 2)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" /");
}
if (conta == 3)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" -");
}
if (conta == 4)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" \\");
conta = 1;
}
break;
}
else (!sensors.getAddress(sensor1, 0));
{
tft.setTextColor(ST7735_RED);
tft.setTextSize(1);
apaga_linha(99, 104);
tft.setCursor(45, 110);
tft.print(" SENSOR ERROR");
tempMin = 999;
tempMax = 0;
}
delay(1000);
tft.fillScreen(ST7735_BLACK);
break;
}
case 1:
{
tft.setRotation(3);
tft.setTextSize(2); // Определяем размер шрифта
tft.setCursor(5, 60); // Устанавливаем курсор в левый верхний угол области вывода
tft.setTextColor(ST7735_BLUE); // Определяем цвет вывода на дисплей
tft.print("loading...");
tft.fillScreen(ST7735_BLACK);
break;
}
}
}
void apaga_linha (int16_t x, int16_t y)
{
tft.fillRect(x, y, 50, 16, ST7735_BLACK);
}
void termo ()
{
tft.drawRect(4, 11, 9, 100, ST7735_WHITE);
// tft.fillRect(5, 12, 7, barra, ST7735_YELLOW);
tft.drawRect(40, 4, 119, 122, ST7735_MAGENTA);
//Рисунок термометра
tft.drawLine(14, 11, 17, 11, ST7735_WHITE); // LINHA DE 100
tft.drawLine(13, 86, 16, 86, ST7735_WHITE); // LINHA DE 75
tft.drawLine(13, 36, 16, 36, ST7735_WHITE); // LINHA DE 25
tft.drawLine(13, 61, 16, 61, ST7735_WHITE); // LINHA DE 50
tft.drawLine(14, 110, 16, 110, ST7735_WHITE); // LINHA DE 0
tft.drawLine(13, 98, 14, 98, ST7735_WHITE); //
tft.drawLine(13, 73, 14, 73, ST7735_WHITE); //
tft.drawLine(13, 48, 14, 48, ST7735_WHITE); //
tft.drawLine(13, 23, 14, 23, ST7735_WHITE); // L
tft.drawCircle(8, 118, 8, ST7735_WHITE);
tft.fillCircle(8, 118, 7, ST7735_RED);
}
//void mostra_endereco_sensor(DeviceAddress deviceAddress)
//{
// for (uint8_t i = 0; i < 8; i++)
// {
// Adiciona zeros se necessário
// if (deviceAddress < 16) Serial.print("0");
//}
//}
Benjamin_:Может кто нибудь подсказать почему?
потому что ты каждый раз постоянно заполняешь экран черным цветом.
tft.fillScreen(ST7735_BLACK);
zverjuga:Benjamin_:Может кто нибудь подсказать почему?
потому что ты каждый раз постоянно заполняешь экран черным цветом.
- код выделить все
tft.fillScreen(ST7735_BLACK);
если этого не делать, то один case будет накладываться на другой.
это нужно сделать только один раз. если нужно изменить содержимое экрана, то один раз его очищаешь и один раз рисуешь что надо. а ты это делаешь с каждым циклом.
zverjuga:это нужно сделать только один раз. если нужно изменить содержимое экрана, то один раз его очищаешь и один раз рисуешь что надо. а ты это делаешь с каждым циклом.
спасибо, это помогло. А подскажите ещё, почему кнопка не всегда срабатывает при переключении с 1-го режима на 2-й. Примерно раз из шести? Со второго на первый- 100% срабатывает.
Вот такой сейчас код переключения режимов:
void loop()
{
if (digitalRead(knopka) == HIGH) {
delay(300);
regim = ++regim;
if (regim > 2) regim = 1;
tft.fillScreen(ST7735_BLACK);
}
if (digitalRead(knopka) == LOW && flag == 1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ...
{
delay(100);
flag = 0; //обнуляем переменную "knopka"
}
switch (regim) {
case 1:
{
//tft print function!
tft.setTextColor(ST7735_YELLOW);
tft.setRotation(3);
tft.setTextSize(2);
tft.setCursor(35, 10);
tft.println(" TEMP = C");
tft.setTextSize(1);
tft.setCursor(131, 10);
tft.println("O");
termo();
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(0);
tft.setCursor(19, 59);
tft.print("50");
tft.setTextSize(0);
tft.setCursor(19, 106);
tft.print("0");
tft.setTextSize(0);
tft.setCursor(19, 7);
tft.print("100");
tft.setTextSize(0);
tft.setCursor(19, 82);
tft.print("25");
tft.setTextSize(0);
tft.setCursor(19, 32);
tft.print("75");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(2);
tft.setCursor(10, 40);
tft.print(" CUR");
tft.setTextSize(2);
tft.setCursor(20, 65);
tft.print(" MIN");
tft.setTextSize(2);
tft.setCursor(20, 90);
tft.print(" MAX");
// Информация датчика темп.
if (sensors.getAddress(sensor1, 0))
{
sensors.requestTemperatures();
float tempC = sensors.getTempC(sensor1);
// Atualiza temperaturas minima e maxima
if (tempC < tempMin)
{
tempMin = tempC;
}
if (tempC > tempMax)
{
tempMax = tempC;
}
barra = (int)tempC;
// Отображаем на ТФТ
tft.setTextColor(ST7735_RED);
apaga_linha(100, 40);
tft.setTextSize(2);
tft.setCursor(100, 40);
tft.println(tempC, 1);
//tft.print("C");
tft.setTextColor(ST7735_GREEN);
apaga_linha(100, 65);
tft.setCursor(100, 65);
tft.println(tempMin, 1);
tft.setTextColor(ST7735_YELLOW);
apaga_linha(100, 90);
tft.setCursor(100, 90);
tft.println(tempMax, 1);
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(1);
apaga_linha(99, 104);
tft.setCursor(45, 110);
tft.print(" SENSOR OK ");
if (tempMin > 50)
tempMin = 999;
tft.fillRect(5, 12, 7, 99, ST7735_RED);
tft.fillRect(5, 12, 7, 100 - barra, ST7735_BLACK);
conta++;
if (conta == 1)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" |");
}
if (conta == 2)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" /");
}
if (conta == 3)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" -");
}
if (conta == 4)
{
tft.setTextSize(1);
tft.setCursor(45, 110);
tft.print(" \\");
conta = 1;
}
break;
}
else (!sensors.getAddress(sensor1, 0));
{
tft.setTextColor(ST7735_RED);
tft.setTextSize(1);
apaga_linha(99, 104);
tft.setCursor(45, 110);
tft.print(" SENSOR ERRO ");
tempMin = 999;
tempMax = 0;
}
delay(1000);
break;
}
case 2:
{
//tft.fillScreen(ST7735_BLACK);
tft.setRotation(3);
tft.setTextSize(2); // Определяем размер шрифта
tft.setCursor(5, 60); // Устанавливаем курсор в левый верхний угол области вывода
tft.setTextColor(ST7735_BLUE); // Определяем цвет вывода на дисплей
tft.print("loading...");
break;
}
}
}
во первых, вместо
regim = ++regim;
пиши
regim += 1;
во вторых, у тебя стоит delay(300), что равно 1/3 секунды. то есть тебе кнопку нужно минимум держать нажатой 1/3 секунды, чтобы код сработал гарантированно. а может и дольше, так как у тебя куча и других delay стоят в других местах. вероятно, в твоем случае играет роль случайность, иногда ты попадаешь в рабочий цикл когда нажимаешь на кнопку, иногда - нет. твой код для таких вещей не совсем оптимален, чтобы в один луп пихать и отрисовку экрана, и чтение кнопок и прочую работу, и при этом делать искусственные задержки.
я тебе рекомендую активнее пользоваться таймерами. заведи отдельную функцию, которая будет срабатывать по таймеру и читать кнопку. прочтенное состояние кнопки сохраняй в отдельной глобальной переменной и уже используй ее в других функциях (например, когда тебе надо переключать режимы). перерисовку экрана также рекомендую делать в отдельной функции по таймеру. использование delay лично в твоем случае не нужное и вредное. внутри loop вообще желательно писать минимум кода или код, который занимается какой нибудь фиговиной, которая не влияет на рабочий код. основной код надо разносить по таймерам или прерываниям.
zverjuga:я тебе рекомендую активнее пользоваться таймерами. заведи отдельную функцию, которая будет срабатывать по таймеру и читать кнопку. прочтенное состояние кнопки сохраняй в отдельной глобальной переменной и уже используй ее в других функциях (например, когда тебе надо переключать режимы). перерисовку экрана также рекомендую делать в отдельной функции по таймеру. использование delay лично в твоем случае не нужное и вредное. внутри loop вообще желательно писать минимум кода или код, который занимается какой нибудь фиговиной, которая не влияет на рабочий код. основной код надо разносить по таймерам или прерываниям.
подскажите пожалуйста ссылку какую нибудь, что бы почитать про эти таймеры, или пример скетча. Мы просто с С++ дружим, а вот с ардуино разбираться начали не так давно. Отсюда и вопросы такие.
Benjamin_, просто в гугле набери "ардуино таймер" и читай - материала полно. таймеры - это по сути прерывания, а с прерываниями нужно дружить.
можно сделать еще проще. пойти в гитхаб и скачать оттуда уже готовые таймеры для ардуино. например DueTimer
https://github.com/ivanseidel/DueTimer
только убедись, что твое железо их поддерживает. если нет, то ищи таймер под твое.
ARTexpress, если посмотреть откомпилированный ассемблерный код, то второй вариант займет 1-2 байт, а первый - больше (3-4). так что я бы не сказал, что шило на мыло.
если компилятор умный, то
++regim
regim++
regim += 1
займет одно и то же.
а вот это
regim = ...
займет дополнительных два байта. а может и больше, так как там возможно потребуется делать временную переменную, чтобы в ней сохранить промежуточный результат.
офлайн
Snoop_Lion
Neophyte Poster
|
|
4 |
8 лет на сайте Город:
|
Уважаемые пользователи форума!Может эта тема где-то тут и праскакивала,но честно признаюсь лень перечитывать! Недавно на просторах интернета увидел такую приблуду -контроллер для аквариума на ардуино. Решил что не помешало бы и себе такой повторить,но сильно они замудрёные и много лишних функций! Так вот к сути вопроса,может кто помочь с подбором компонентов и написанием скетча,если да то потом напишу что я хочу от контроллера!Заранее благодарен!
Snoop_Lion:Решил что не помешало бы и себе такой повторить
А выглядит так, был то "пусть кто то за меня его повторит"...