Отображение температуры с DS18B20 на LED матрице

gryadkinn
Offline
Зарегистрирован: 10.12.2017

Всем привет. Не могу разобраться с отображением значения температуры на матрицах 8х32 под управлением MAX7219 с датчика DS18B20. Первое, с чем столкнулся, это возможность отображать не бегущей строкой, а статично. Примеров пересмотрел куча, но нужного так и не нашел. Каким кодом можно выводить данные?

Как я понимаю, нужно записывать данные температуры с датчика в переменную и эту переменную потом считывать и отправлять на дисплей. Но что-то не выходит.

Готов отблагодарить материально, бъюсь уже две недели.

sadman41
Offline
Зарегистрирован: 19.10.2016

Над чем бъетесь-то две недели - над получением температуры или над выводом? 

gryadkinn
Offline
Зарегистрирован: 10.12.2017

Именно над выводом. Не понимаю, как отобразить переменнуюв статичном варианте, не бегущей строкой. В бегущем варианте тоже проблема, так как при чтении температуры получается число, а код, который я нашел выводит строку, получается конфликт.

 

float temperature() {                            // Измеряем температуру 10 секунд
  digitalWrite(term_power, HIGH);                // Включаем питание датчика температуры
  delay(200);                                    // Задержка перед первым измерением 
  sensors.requestTemperatures();                 // Запрос на измерение температуры (1-й ошибочный)
  delay(650);                                    // Задержка перед поторным измерением
  sensors.requestTemperatures();                 // Запрос на измерение температуры (повторный)
  float t = float(sensors.getTempCByIndex(0));   // Получаем значение температуры
  digitalWrite(term_power, LOW);                 // Отключаем питание датчика температуры
  delay(1400);                                   // Задержка, чтобы датчик не нагревался от частых измерений
  return(t);                                     // Возвращаем значение температуры в место вызова функци
}
void loop(void)
 {
  // здесь в зависимости от перменых на матрицу выводится нужная строка
  if (stroka == 0) {
  tape = utf8rus(sensors.getTempCByIndex(0));
  

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Вообще ничего не понимаю. Функцию запроса температуры нигде не вызываете, вместо вывода перекодировку кодовой страницы делаете, какие библиотеки используете - неясно. Запостите простой код, где вы выводите, например, строку "Temp". 

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

Не знаю, разберетесь или нет ... мой вариант термометра на MAX7219, только у меня три индикатора, но это не меняет сути, просто укажите, что у вас их 4 ...

/****************************************************** Версия от 01/04/2017 *******************************************************/
// В версии от 14/09/2016 добавлены малые цифры и функция вывода их на матрицу
//
//
//
#include "LedControl.h"
#include "OneWire.h"
#include "DallasTemperature.h"

/****************************************************** Объявление констант ******************************************************/

// Выход данных датчика температуры подключен к pin2 Arduino
#define one_wire_bus 2

// Создаем экземпляр класса oneWire, передаевая ему параметр (номер пина Arduino)
OneWire oneWire(one_wire_bus);

//
DallasTemperature sensors(&oneWire);

// Описание используемых ножек Arduino
 int dataPin = 12;
 int clkPin = 11;
 int csPin = 10;
 
 // Переменная numDisplay определяет число матричных 8*8 индикаторов в массиве
 // Нумерация индикаторов начинается с 0
 // Нумерация столбцов и строк индикатора также начинается с 0
 //
 int numDisplay = 3; 

 // Переменная temp хранит считанную с датчика температуру
float temp; 

// Массив цифр 5*8
byte digitM[][5] = {{B01111110,B10000001,B10000001,B10000001,B01111110},
                {B10000100,B10000010,B11111111,B10000000,B10000000},
                {B11000010,B10100001,B10010001,B10001001,B10000110},
                {B01000010,B10000001,B10001001,B10001001,B01110110},
                {B00110000,B00101000,B00100100,B00100010,B11111111},
                {B01001111,B10001001,B10001001,B10001001,B01110001},
                {B01111110,B10001001,B10001001,B10001001,B01110010},
                {B00000011,B11100001,B00010001,B00001001,B00000111},
                {B01110110,B10001001,B10001001,B10001001,B01110110},
                {B01001110,B10010001,B10010001,B10010001,B01111110},
                {B00000000,B00000000,B00000000,B00000000,B00000000}
               };

// Массив малых цифр 3*6(десятичные доли градуса)
byte digitD[][3]={{B01111000,B10000100,B01111000},
                  {B10001000,B11111100,B10000000},
                  {B11000100,B10100100,B10011100},
                  {B10000100,B10010100,B11101100},
                  {B00111100,B00100000,B11111000},
                  {B10011100,B10010100,B11110100},
                  {B11111100,B10010100,B11110100},
                  {B11000100,B00100100,B00011100},
                  {B11111100,B10010100,B11111100},
                  {B10111100,B10100100,B11111100}};


// Массив малых цифр 4*6(десятичные доли градуса)
byte digitDv1[][4]={{B01111000,B10000100,B10000100,B01111000},
                  {B00000000,B10001000,B11111100,B10000000},
                  {B10001000,B11000100,B10100100,B10011000},
                  {B01001000,B10000100,B10010100,B01101000},
                  {B00110000,B00101000,B00100100,B11110000},
                  {B01011100,B10010100,B10010100,B01100100},
                  {B01111000,B10010100,B10010100,B01100000},
                  {B10000100,B01000100,B00100100,B00011100},
                  {B01101000,B10010100,B10010100,B01101000},
                  {B00011000,B10100100,B10100100,B01111000}};                  

// Знак разделения целой и дробной частей показаний температуры
byte delimiter[][1] = {{B11000000}};

// Знак плюс +
byte plus[][3] = {{B00010000,B00111000,B00010000}};

// Знак минус -
byte minus[][3] = {{B00001000,B00001000,B00001000}};

// Массив знака градусов и символа Цельсия (С)
byte celsius[][7] = {{B00000011,B00000011,B00000000,B00011110,B00100001,B00100001,B00010010}};
              
// Создаем экземпляр класса LedControl//
//
LedControl lc=LedControl(dataPin, clkPin, csPin, numDisplay);

// Функция возвращает номер активного столбца в пределах индикатора
// Вычисляем номер отображаемого (текущего) столбца в пределах индикатора.
// Как пример:
// Нам нужно вывести массив, начиная с 22-й позиции индикатора
// 1-я позиция: 22-((22/8)*8 + 0) = 22
//
// 22 - (22/8)*8 = 22 - 2*8 = 6
// Т.е. начинаем выводить, начиная с 6-й позиции
//
int fnNumIndicatorColumn(int startPosition, int arrayIndex)
{
  if((startPosition - (startPosition/8)*8 + arrayIndex) > 7)
  { return (startPosition - (startPosition/8)*8 + arrayIndex) - 8;}
  else
  { return ((startPosition - (startPosition/8)*8) + arrayIndex);}
}

// Функция возвращает номер активного индикатора 
int fnCurentIndicator(int startPosition, int arrayIndex)
{
  return (startPosition + arrayIndex)/8;
}

// Функция стирает все индикатоы
void fnClearAllDevices(int numberDev)
{
   for(int l=0; l<numDisplay; l++)
  {
   lc.clearDisplay(l);
  }
}

void setup()
{

// Устанавливаем яркость индикаторов
// Значение яркости от 0 до 15
    lc.setIntensity(0,1);
    lc.setIntensity(1,1);
    lc.setIntensity(2,1);
  
    lc.shutdown(0,false);
    lc.shutdown(1,false);
    lc.shutdown(2,false);
    
    fnClearAllDevices(3);  

    // Инициализация датчика температуры
    sensors.begin();
}

// Функция выводит на матрицу заданную строку из массива digitToShow, начиная с заданной позиции
// Номер выводимой строки определяется передаваемым параметром dig 
// Всего число позиций матрицы равно 8*numDisplay, от 0 до 8*numDisplay-1
// Число индикаторов - numDisplay, переменная curDev определяет текущий индикатор, куда пишем столбец
// Число точек в каждом индикаторе - 8
// Переменная k определяет номер выводимого столбца из массива digitToShow
// Переменная i определяет номер столба в пределах индикатора: допустим, нужно вывести первый столбец в 23-ю позицию матрицы;
// 1. определяем номер индикатора (нумерация индикаторов также начинается с 0): curDev = (startPos + k)/8; (23+0)/8 = 2
// 2. определяем номер столбца в пределах индикатора: i = startPos - (startPos/8)*8; 23 - (23/8)*8 = 23 - 16 = 7,
// т.е. первый элемент массива выводим в 7-й столбец 3-го индикатора

// Входной параметр startPos определяет стартовую позицию, с которой начинаем выводить символ

// Другой вариант вывода больших цифр на матрицу
// Функции передаем цифру, которую нужно вывести на индикатор и начальную позицию, с которой начинаем выводить

void fnShowBigDigit(int digit2Show, int startPosition)
{ 
  for(int k=0; k<5; k++)      // Пробегаем по всем элементам выводимого массива, в нашем случае размерность равна 5
  {

// Определяем номер столбца (от 0 до 7) индикатора, в который будем писать. Общее число столбцов от 0 до 31
// Если значение i будет больше, то обнуляем его

  //lc.setColumn(fnCurentIndicator(startPosition,k),fnNumIndicatorColumn(startPosition,k),digitM[digit2Show][k]);
  lc.setRow(fnCurentIndicator(startPosition,k),fnNumIndicatorColumn(startPosition,k),digitM[digit2Show][k]);

  }  
}

// Функция выводит на матрицу малые цифры
void fnShowSmallDigit(int digit2Show, int startPosition)
{
  for(int k=0; k<4; k++)      // Пробегаем по всем элементам выводимого массива, в нашем случае размерность равна 4
  {

// Определяем номер столбца (от 0 до 7) индикатора, в который будем писать. Общее число столбцов от 0 до 31
// Если значение i будет больше, то обнуляем его

  lc.setRow(fnCurentIndicator(startPosition,k),fnNumIndicatorColumn(startPosition,k),digitDv1[digit2Show][k]);
  //lc.setColumn(fnCurentIndicator(startPosition,k),fnNumIndicatorColumn(startPosition,k),digitDv1[digit2Show][k]);

  }  
}

/***************************************************** 14/02/2016 ***************************************************/
// Функция выводит на матричный индикатор термометра целую часть данных температуры датчика.
// Позиции вывода строго заданы
//
//
void fnShowTwoBigDigit(double dsTemp)
{
  int k;      // Целая часть значения температуры
  int d10;    // Цифра десятков
  int d1;     // Цифра едениц
  int g;      // дробная часть температуры

// Выделяем первую цифру
  k = dsTemp;
  d10 = k/10;

// Выделяем вторую цифру
  d1 = k - d10*10;

// Выделяем дробную часть

g = dsTemp*10;
g = g - ((d10*10 + d1)*10);

// "Рисуем" старшую цифру, затем младшую цифру
fnShowBigDigit(d10,4);
fnShowBigDigit(d1,10);
fnShowDelimiter();
fnShowSmallDigit(g,18);
}

/***************************************************** 08/02/2016 ***************************************************/
// Функция вывода знака температуры Цельсия
// 
//void fnShowCelsius()
//{
//  for(int m=0; m<7; m++)
//  {
//    lc.setColumn(2,m+1,celsius[0][m]);
//  }
  
//}

/***************************************************** 09/02/2016 ***************************************************/
// Функция вывода знака плюс
// 
void fnShowPlus()
{
  for(int i=0;i<3;i++)
  {
    lc.setRow(0,i,plus[0][i]);
  }  
}

/***************************************************** 09/02/2016 ***************************************************/
// Функция вывода знака минус
// 
void fnShowMinus()
{
    for(int i=0;i<3;i++)
  {
    lc.setRow(0,i,minus[0][i]);
  }  
}

//
void fnShowDelimiter()
{
  lc.setRow(2,0,delimiter[0][0]);
  }

/***************************************************** 09/02/2016 ***************************************************/
// Основной цикл работы программы
//
void loop()
{
  
// Запрашиваем температуру с датчика  
  sensors.requestTemperatures();  
  
// Считываем температуру с датчика и передаем это значение функции
  fnShowTwoBigDigit(sensors.getTempCByIndex(0));
  fnShowPlus();
//  fnShowCelsius();

  }

 

gryadkinn
Offline
Зарегистрирован: 10.12.2017

Сверху я привел кусок кода, а нге целиком, поэтому, возможно меня трудно понять. 

Если сначала, то:

Есть матричный дисплей 8x32 под управлением MAX7219. Есть датчик DS18B20. Надо вывести значение температуры с датчика, на матричный дисплей в статичном режиме.

Пока имею следующее:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4 //контакт линии данных
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float temp = sensors.getTempCByIndex(0);
 
void setup(void)
{
  // запускаем последовательную коммуникацию (в отладочных целях):
  Serial.begin(9600);
  // запускаем библиотеку:
  sensors.begin();
}

void loop(void){
  // вызываем функцию sensors.requestTemperatures(),
  // которая приказывает всем устройствам, подключенным к шине,
  // выполнить конверсию температурных данных:
 
  sensors.requestTemperatures();
 
  Serial.println(temp);
  delay(500);
  }

Как теперь значение temp вывести на дисплей? Библиотека - любая, которая сделает это как можно проще.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

мой вариант не устраивает? Тогда увы .... мне пора на горшок и спать :)

gryadkinn
Offline
Зарегистрирован: 10.12.2017

Спасибо! Осталось только разорбраться с поворотом матриц, ибо получается все повернуто на 90*

UPD, не сразу увидел ваше предложение.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

gryadkinn пишет:

Спасибо! Осталось только разорбраться с поворотом матриц, ибо получается все повернуто на 90*

UPD, не сразу увидел ваше предложение.

Да, совершенно верно, библиотека написана в предположении, что разъем матриц расположен горизонтально, я же для удобства пайки расположил разъемы вертикально. Поищине на форуме, я писал с фотками, как это исправить .. ну в общем, столбы нужно поменять со строками и все будет как надо

bwn
Offline
Зарегистрирован: 25.08.2014

Типа так:

void staticText (String tape) {

  int x = (matrix.width() + 2 - (tape.length() * width)) / 2; //выравнивание по центру X
  //int y = (matrix.height() - 8) / 2; //выравнивание по центру Y
  int y = 0; //Для однострочной матрицы

  matrix.fillScreen(LOW);

  for ( int i = 0 ; i < tape.length(); i++ ) {
    matrix.drawChar(x, y, tape[i], HIGH, LOW, 1);
    x += width;
  }
  matrix.write(); // отправка данных на дисплей
}

Для   Adafruit_GFX.h и Max72xxPanel.h

В функцию отправляете свой String для отображения.
gryadkinn
Offline
Зарегистрирован: 10.12.2017

Я не смог понять, что надо менять в коде для поворота. Позиции символов нашел, а поворот не осуществить. Пост на форуме нашел, но его применить к коду не смог.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

gryadkinn пишет:

Я не смог понять, что надо менять в коде для поворота. Позиции символов нашел, а поворот не осуществить. Пост на форуме нашел, но его применить к коду не смог.

Мне щас совершенно некогда помочь, т.к. завтра должен сдать кое-какой проект ... начните с простого, поэкспериментируйте с выводим просто точки с заданными координатами, либо просто-напросто переделайте массив изображений, который я вывожу на матрицы

gryadkinn
Offline
Зарегистрирован: 10.12.2017

Как раз массив и думал переделать. Удачи в проекте!

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

gryadkinn пишет:

Как раз массив и думал переделать. Удачи в проекте!

Спасибо, я еще хочу, будет время добавить типа стрелочки, которая будет показывать как ведет себя температура, скажем в течении получаса - растет или понижается

S_Sergey_G
Offline
Зарегистрирован: 27.01.2021

ulis пишет:

[Да, совершенно верно, библиотека написана в предположении, что разъем матриц расположен горизонтально, я же для удобства пайки расположил разъемы вертикально. Поищине на форуме, я писал с фотками, как это исправить .. ну в общем, столбы нужно поменять со строками и все будет как надо

Конечно прошло много времени, только начал заниматься Ардуино. Нашел Ваш скечь термометра. По Вашей инструкции заменил солбы на строки. Изображение повернулось, но в зеркальном виде. Перевернул массив, все встало на место. Но как то странно. Знак плюс оказался вторым знаком, все сдвинулось.  Вот такой вид стал ( 2+5 . 3 ). Как можно исправить это?