ARDUINO Дальномер своими руками. Обсуждение проекта

Диана

✩✩✩✩✩✩✩
5 Май 2023
2
0
Под новую библиотеку "SevenSegmentsDisp" кто нибудь переделывал ?
С старой (TM74HC595-Gyver) как в статье у дисплея горят абсолютно все сегменты и быстро мерцают, даже в примерах.
Просто замена одной библиотеки на другую не помогла, всё на что ругался IDE - закомментировала в //old

C++:
//Created 2017 by AlexGyver

// -------НАСТРОЙКИ-------
// длина корпуса в сантиметрах, для переноса начала отсчёта в заднюю часть корпуса
float case_offset = 10.0;
// -------НАСТРОЙКИ-------

// сонар
#define ECHO 2
#define TRIG 3
#define sensVCC 4

// дисплей
#define dispGND 5
#define DATA_PIN   6
#define SCLK_PIN   8
#define RCLK_PIN   7
#define dispVCC 9

// переключатель
#define buttPIN 11
#define buttGND 12

// создаём дисплей
//old #include <TM74HC595Display.h>
#include <SevenSegmentsDisp.h>
#include <TimerOne.h>
//old TM74HC595Display disp(SCLK, RCLK, DIO);
Disp595 disp(DATA_PIN, SCLK_PIN, RCLK_PIN);
unsigned char SYM[47];

// крутая библиотека сонара
#include <NewPing.h>
NewPing sonar(TRIG, ECHO, 400);

float dist_3[3] = {0.0, 0.0, 0.0};   // массив для хранения трёх последних измерений
float middle, dist, dist_filtered;
float k;
byte i, delta;
unsigned long dispIsrTimer, sensTimer;

void setup() {
  Serial.begin(9600);
  symbols();            // создать символы для отображения на дисплее

  // настройка пинов
  pinMode(sensVCC, OUTPUT);
  pinMode(dispGND, OUTPUT);
  pinMode(dispVCC, OUTPUT);
  pinMode(buttPIN, INPUT_PULLUP);
  pinMode(buttGND, OUTPUT);

  // подаём сигналы на пины
  digitalWrite(sensVCC, 1);
  digitalWrite(dispGND, 0);
  digitalWrite(dispVCC, 1);
  digitalWrite(buttGND, 0);
}

void loop() {
  if (millis() - sensTimer > 50) {                          // измерение и вывод каждые 50 мс
    // счётчик от 0 до 2
    // каждую итерацию таймера i последовательно принимает значения 0, 1, 2, и так по кругу
    if (i > 1) i = 0;
    else i++;

    dist_3[i] = (float)sonar.ping() / 57.5;                 // получить расстояние в текущую ячейку массива
    if (!digitalRead(buttPIN)) dist_3[i] += case_offset;    // если включен переключатель стороны измерения, прибавить case_offset
    dist = middle_of_3(dist_3[0], dist_3[1], dist_3[2]);    // фильтровать медианным фильтром из 3ёх последних измерений

    delta = abs(dist_filtered - dist);                      // расчёт изменения с предыдущим
    if (delta > 1) k = 0.7;                                 // если большое - резкий коэффициент
    else k = 0.1;                                           // если маленькое - плавный коэффициент

    dist_filtered = dist * k + dist_filtered * (1 - k);     // фильтр "бегущее среднее"

    disp.clear();                                           // очистить дисплей
    //old disp.float_dot(dist_filtered, 1);                       // вывести
    disp.displayFloat(dist_filtered, 1);                       // вывести
    sensTimer = millis();                                   // сбросить таймер
  }

//old  if (micros() - dispIsrTimer > 300) {       // таймер динамической индикации (по-русски: КОСТЫЛЬ!)
//old    disp.timerIsr();                         // "пнуть" дисплей
//old    dispIsrTimer = micros();                 // сбросить таймер
//old  }
}

// медианный фильтр из 3ёх значений
float middle_of_3(float a, float b, float c) {
  if ((a <= b) && (a <= c)) {
    middle = (b <= c) ? b : c;
  }
  else {
    if ((b <= a) && (b <= c)) {
      middle = (a <= c) ? a : c;
    }
    else {
      middle = (a <= b) ? a : b;
    }
  }
  return middle;
}

// символы для дисплея
void symbols() {
  // обычные
  SYM[0] = 0xC0; //0
  SYM[1] = 0xF9; //1
  SYM[2] = 0xA4; //2
  SYM[3] = 0xB0; //3
  SYM[4] = 0x99; //4
  SYM[5] = 0x92; //5
  SYM[6] = 0x82; //6
  SYM[7] = 0xF8; //7
  SYM[8] = 0x80; //8
  SYM[9] = 0x90; //9

  // с точкой
  SYM[10] = 0b01000000; //0.
  SYM[11] = 0b01111001; //1.
  SYM[12] = 0b00100100; //2.
  SYM[13] = 0b00110000; //3.
  SYM[14] = 0b00011001; //4.
  SYM[15] = 0b00010010; //5.
  SYM[16] = 0b00000010; //6.
  SYM[17] = 0b01111000; //7.
  SYM[18] = 0b00000000; //8.
  SYM[19] = 0b00010000; //9.
}
 

poty

★★★★★★✩
19 Фев 2020
3,228
939

@Диана, всю динамическую индикацию закомментировали и хотите, чтобы что-то отображалось?
 

Диана

✩✩✩✩✩✩✩
5 Май 2023
2
0

@Диана, всю динамическую индикацию закомментировали и хотите, чтобы что-то отображалось?
думала хватит и этого
//old disp.float_dot(dist_filtered, 1); // вывести
disp.displayFloat(dist_filtered, 1); // вывести
в "примерах" новой библиотеке никаких "КОСТЫЛЕЙ" не было, по этому закомментировала 83-86, да и не знаю что вместо неё нужно писать - а с ними не компилировалось.
 

SacredSinner

✩✩✩✩✩✩✩
25 Май 2023
1
0
Добрый день всем! Имеется проблема. Подскажите, пожалуйста.
Решил немного переделать проект и заменить датчик расстояния на vl53l0x/
Первая сложность, с которой столкнулся, на дисплее ярко светился только первый символ. Заменил строки скетча, которые "пинают" дисплей на строки из примера из комплекта библиотеки. Яркость нормализовалась. Проблема решена.
Далее мне нужно сделать две кнопки. Взял класс из этого урока: https://alexgyver.ru/lessons/arduino-buttons/. Создал в скетче для кнопок два объекта из этого класса. И вот тут затык. Как только я добавляю строчку if (btn1.click())... ардуина зависает, на дисплей ничего не выводится, в мониторе порта тоже. Не могу понять, где косяк
Вот в таком виде код работает:
C++:
//Created 2017 by AlexGyver

// -------НАСТРОЙКИ-------
//Начальный сдвиг в мм
int offset = -30;
// -------НАСТРОЙКИ-------

#include "button.h"
#include "Wire.h"
// кнопки
button btn1(3);
button btn2(2);

// дисплей
#define dispGND 5
byte DIO = 6;
byte RCLK = 7;
byte SCLK = 8;
#define dispVCC 9

// создаём дисплей
#include <TM74HC595Display.h>
#include <TimerOne.h>
TM74HC595Display disp(SCLK, RCLK, DIO);
unsigned char SYM[47];


//библитоека сенсора
#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X lox = Adafruit_VL53L0X();


float dist_3[3] = {0.0, 0.0, 0.0};   // массив для хранения трёх последних измерений
float middle, dist, dist_filtered;
float k;
byte i, delta;
unsigned long dispIsrTimer, sensTimer;

void setup() {
  Serial.begin(9600);
  symbols();            // создать символы для отображения на дисплее

  // настройка пинов
  pinMode(dispGND, OUTPUT);
  pinMode(dispVCC, OUTPUT);

 
  // подаём сигналы на пины
  digitalWrite(dispGND, 0);
  digitalWrite(dispVCC, 1);

//настройка сенсора
lox.begin();

// динамическая индикация
Timer1.initialize(1000);
Timer1.attachInterrupt(timerIsr);
}

void loop() {


  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false);

  if (millis() - sensTimer > 200) {                          // измерение и вывод каждые 200 мс
    // счётчик от 0 до 2
    // каждую итерацию таймера i последовательно принимает значения 0, 1, 2, и так по кругу
    if (i > 1) i = 0;
    else i++;

    dist_3[i] = (float)measure.RangeMilliMeter;                 // получить расстояние в текущую ячейку массива
    dist_3[i] += offset;    // прибавить offset
    dist = middle_of_3(dist_3[0], dist_3[1], dist_3[2]);    // фильтровать медианным фильтром из 3ёх последних измерений

    delta = abs(dist_filtered - dist);                      // расчёт изменения с предыдущим
    if (delta > 1) k = 0.7;                                 // если большое - резкий коэффициент
    else k = 0.1;                                           // если маленькое - плавный коэффициент

    dist_filtered = dist * k + dist_filtered * (1 - k);     // фильтр "бегущее среднее"

    disp.clear();                                           // очистить дисплей
    disp.float_dot(dist_filtered/10, 1);                       // вывести
    sensTimer = millis();                                   // сбросить таймер
    
    }

}

// медианный фильтр из 3ёх значений
float middle_of_3(float a, float b, float c) {
  if ((a <= b) && (a <= c)) {
    middle = (b <= c) ? b : c;
  }
  else {
    if ((b <= a) && (b <= c)) {
      middle = (a <= c) ? a : c;
    }
    else {
      middle = (a <= b) ? a : b;
    }
  }
  return middle;
}

void timerIsr()
{
  disp.timerIsr();
}


// символы для дисплея
void symbols() {
  // обычные
  SYM[0] = 0xC0; //0
  SYM[1] = 0xF9; //1
  SYM[2] = 0xA4; //2
  SYM[3] = 0xB0; //3
  SYM[4] = 0x99; //4
  SYM[5] = 0x92; //5
  SYM[6] = 0x82; //6
  SYM[7] = 0xF8; //7
  SYM[8] = 0x80; //8
  SYM[9] = 0x90; //9

  // с точкой
  SYM[10] = 0b01000000; //0.
  SYM[11] = 0b01111001; //1.
  SYM[12] = 0b00100100; //2.
  SYM[13] = 0b00110000; //3.
  SYM[14] = 0b00011001; //4.
  SYM[15] = 0b00010010; //5.
  SYM[16] = 0b00000010; //6.
  SYM[17] = 0b01111000; //7.
  SYM[18] = 0b00000000; //8.
  SYM[19] = 0b00010000; //9.
}
Стоит только добавить в void loop() условие нажатия кнопки, всё - приехали...
 
Изменено: