Индикатор TM1637. Как убрать число 85?
- Войдите на сайт для отправки комментариев
Доброго времени суток! При помощи Attiny85 сделал термометр, чтобы показывал уличную температуру. Датчик DS18B20, индикатор ТМ1637. Код брал из Интернета. Залил в Аттини85, все работает, прекрасно. За исключением одной маленькой неприятности: как только подается напряжение на весь термометр, показывается цифра 85, и только после секундной задержки появляется собственно температура. Просмотрел код и библиотеку, но ничего не нашел. Никакого оператора display, который бы выводил 85. Помогите, пожалуйста, убрать это число, чтобы температура выводилась без задержек.
Программа в Ардуино IDE:
#include <TM1637Display.h> #include <OneWire.h> //------------------------------------- Дополнительные установки -------------------------- int inTSensorConnectedPin = 0; OneWire ds1(inTSensorConnectedPin); int pinCLK = 2; int pinDIO = 3; TM1637Display display(pinCLK, pinDIO); //------------------------------------- SETUP --------------------------------------------- void setup() { } //----------------------------------------- LOOP ------------------------------------------ void loop() { display.setBrightness(0x0f); bool DisplayNulls = false; float temp = getInsideTemp(); display.showNumberDec(temp, DisplayNulls); delay(500); } float getInsideTemp() { byte data[12]; byte addr[8]; if ( !ds1.search(addr)) { //error NO more addrss ds1.reset_search(); return -1001; } if ( OneWire::crc8( addr, 7) != addr[7]) { //error CRC is not valid! return -1002; } if ( addr[0] != 0x10 && addr[0] != 0x28) { //error NOT recognizd! return -1003; } ds1.reset(); ds1.select(addr); ds1.write(0x44,1); byte present = ds1.reset(); ds1.select(addr); ds1.write(0xBE); for (int i = 0; i < 9; i++) { data[i] = ds1.read(); } ds1.reset_search(); byte MSB = data[1]; byte LSB = data[0]; float TRead = ((MSB<<8) | LSB); float Temperature = TRead / 16; return Temperature; }
Библиотека TM1637Display.h:
#ifndef __TM1637DISPLAY__ #define __TM1637DISPLAY__ #include <inttypes.h> #define SEG_A 0b00000001 #define SEG_B 0b00000010 #define SEG_C 0b00000100 #define SEG_D 0b00001000 #define SEG_E 0b00010000 #define SEG_F 0b00100000 #define SEG_G 0b01000000 #define DEFAULT_BIT_DELAY 100 class TM1637Display { public: TM1637Display(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay = DEFAULT_BIT_DELAY); void setBrightness(uint8_t brightness, bool on = true); void setSegments(const uint8_t segments[], uint8_t length = 4, uint8_t pos = 0); //! Clear the display void clear(); void showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); void showNumberDecEx(int num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); void showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); uint8_t encodeDigit(uint8_t digit); protected: void bitDelay(); void start(); void stop(); bool writeByte(uint8_t b); void showDots(uint8_t dots, uint8_t* digits); void showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); private: uint8_t m_pinClk; uint8_t m_pinDIO; uint8_t m_brightness; unsigned int m_bitDelay; }; #endif // __TM1637DISPLAY__
Файл TM1637Display.cpp, который был в папке ТМ1637. Выкладываю на всякий случай, может, нужен.:
// Author: avishorp@gmail.com // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA extern "C" { #include <stdlib.h> #include <string.h> #include <inttypes.h> } #include <TM1637Display.h> #include <Arduino.h> #define TM1637_I2C_COMM1 0x40 #define TM1637_I2C_COMM2 0xC0 #define TM1637_I2C_COMM3 0x80 // // A // --- // F | | B // -G- // E | | C // --- // D const uint8_t digitToSegment[] = { // XGFEDCBA 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111, // 9 0b01110111, // A 0b01111100, // b 0b00111001, // C 0b01011110, // d 0b01111001, // E 0b01110001 // F }; static const uint8_t minusSegments = 0b01000000; TM1637Display::TM1637Display(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay) { // Copy the pin numbers m_pinClk = pinClk; m_pinDIO = pinDIO; m_bitDelay = bitDelay; // Set the pin direction and default value. // Both pins are set as inputs, allowing the pull-up resistors to pull them up pinMode(m_pinClk, INPUT); pinMode(m_pinDIO,INPUT); digitalWrite(m_pinClk, LOW); digitalWrite(m_pinDIO, LOW); } void TM1637Display::setBrightness(uint8_t brightness, bool on) { m_brightness = (brightness & 0x7) | (on? 0x08 : 0x00); } void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos) { // Write COMM1 start(); writeByte(TM1637_I2C_COMM1); stop(); // Write COMM2 + first digit address start(); writeByte(TM1637_I2C_COMM2 + (pos & 0x03)); // Write the data bytes for (uint8_t k=0; k < length; k++) writeByte(segments[k]); stop(); // Write COMM3 + brightness start(); writeByte(TM1637_I2C_COMM3 + (m_brightness & 0x0f)); stop(); } void TM1637Display::clear() { uint8_t data[] = { 0, 0, 0, 0 }; setSegments(data); } void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, uint8_t pos) { showNumberDecEx(num, 0, leading_zero, length, pos); } void TM1637Display::showNumberDecEx(int num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos) { showNumberBaseEx(num < 0? -10 : 10, num < 0? -num : num, dots, leading_zero, length, pos); } void TM1637Display::showNumberHexEx(uint16_t num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos) { showNumberBaseEx(16, num, dots, leading_zero, length, pos); } void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos) { bool negative = false; if (base < 0) { base = -base; negative = true; } uint8_t digits[4]; if (num == 0 && !leading_zero) { // Singular case - take care separately for(uint8_t i = 0; i < (length-1); i++) digits[i] = 0; digits[length-1] = encodeDigit(0); } else { //uint8_t i = length-1; //if (negative) { // // Negative number, show the minus sign // digits[i] = minusSegments; // i--; //} for(int i = length-1; i >= 0; --i) { uint8_t digit = num % base; if (digit == 0 && num == 0 && leading_zero == false) // Leading zero is blank digits[i] = 0; else digits[i] = encodeDigit(digit); if (digit == 0 && num == 0 && negative) { digits[i] = minusSegments; negative = false; } num /= base; } if(dots != 0) { showDots(dots, digits); } } setSegments(digits, length, pos); } void TM1637Display::bitDelay() { delayMicroseconds(m_bitDelay); } void TM1637Display::start() { pinMode(m_pinDIO, OUTPUT); bitDelay(); } void TM1637Display::stop() { pinMode(m_pinDIO, OUTPUT); bitDelay(); pinMode(m_pinClk, INPUT); bitDelay(); pinMode(m_pinDIO, INPUT); bitDelay(); } bool TM1637Display::writeByte(uint8_t b) { uint8_t data = b; // 8 Data Bits for(uint8_t i = 0; i < 8; i++) { // CLK low pinMode(m_pinClk, OUTPUT); bitDelay(); // Set data bit if (data & 0x01) pinMode(m_pinDIO, INPUT); else pinMode(m_pinDIO, OUTPUT); bitDelay(); // CLK high pinMode(m_pinClk, INPUT); bitDelay(); data = data >> 1; } // Wait for acknowledge // CLK to zero pinMode(m_pinClk, OUTPUT); pinMode(m_pinDIO, INPUT); bitDelay(); // CLK to high pinMode(m_pinClk, INPUT); bitDelay(); uint8_t ack = digitalRead(m_pinDIO); if (ack == 0) pinMode(m_pinDIO, OUTPUT); bitDelay(); pinMode(m_pinClk, OUTPUT); bitDelay(); return ack; } void TM1637Display::showDots(uint8_t dots, uint8_t* digits) { for(int i = 0; i < 4; ++i) { digits[i] |= (dots & 0x80); dots <<= 1; } } uint8_t TM1637Display::encodeDigit(uint8_t digit) { return digitToSegment[digit & 0x0f]; }
Значение 85 это норма от сенсор DS18X20 если вы сенсор не просили начать температурное измерение.
Помогите, пожалуйста, убрать это число, чтобы температура выводилась без задержек.
"Без задержек" не выйдет, измерение температуры этим датчиком занимает заметное время - в стандартной библиотке примерно 0.8 секунды.
Вы просто не выводите туда 85, тогда и убирать не придётся. Выводите только тогда,когда сенсор начнёт нормальные значения выдавать.
Первое выдаваемое значение 85 служит для
того чтобы сообщить что он жив.
В setup запускаете первое преобразование, без считывания результата, делаете задержку на преобразование и в loop уже будет нормально работать.
Помогите, пожалуйста, убрать это число, чтобы температура выводилась без задержек.
"Без задержек" не выйдет, измерение температуры этим датчиком занимает заметное время - в стандартной библиотке примерно 0.8 секунды.
Выйдет, если не пользоваться какой. В шину достаточно раз в N секунд давать команду на запуск конвертации (при этом пропуская адреса ROM, т.е. для всех датчиков на линии), и уже когда хочется, в любой момент времени - читать с конкретного датчика. Дебильная задержка в 0.8 секунд в дебильной библиотеке - вообще не нужна, т.к. датчик всегда отдаёт значение температуры, а вот изменяется оно во внутренней памяти датчика - только после окончания конвертации, которая (конвертация) занимает некое время, описанное в даташите на каждую разрядность измерений.
Выйдет, если не пользоваться какой. В шину достаточно раз в N секунд давать команду на запуск конвертации ....
ты какой-то резкий сегодня. Лезешь в спор, где его нет.
Речь о том, что СРАЗУ ПОСЛЕ ВКЛЮЧЕНИЯ значение температуры с датчика не получить - что с "дебильной либой", что без нее. Один раз конверсию подождать всяко придется. Дефолтное время - 750мс.
ты какой-то резкий сегодня.
Понедельник :)
Лезешь в спор, где его нет.
Не, не спорил, просто на всякий.
Речь о том, что СРАЗУ ПОСЛЕ ВКЛЮЧЕНИЯ значение температуры с датчика не получить - что с "дебильной либой", что без нее. Один раз конверсию подождать всяко придется. Дефолтное время - 750мс.
Ну не согласен в терминах. Сразу после включения - можно получить температуру. Ждать - не надо ничего. А вот вопрос - будет ли правильной полученная температура - это совершенно другое. Правильный ответ такой: температура будет правильной после окончания конвертации, которая произойдёт через N времени после команды запуска конвертации. Ждать - не надо, надо просто при старте запустить конвертацию, а начать выводить информацию - после её завершения. И - никаких ожиданий, пускай всё работает параллельно. Щас псевдокод накидаю.
Вот псевдокод без ждать:
Нигде не жду, никого не жду :)
Сам запуск конвертации:
Уже почти весь код написан :)
"Без задержек" не выйдет, измерение температуры этим датчиком занимает заметное время - в стандартной библиотке примерно 0.8 секунды.
Хорошо, можно подождать 0.8 секунды. Хотелось бы только, чтобы цифра 85 не мозолила глаза каждый раз, когда буду узнавать температуру на улице.
Хорошо, можно подождать 0.8 секунды. Хотелось бы только, чтобы цифра 85 не мозолила глаза каждый раз, когда буду узнавать температуру на улице.
Чтобы научится отличать температуру 85 от ошибки связи, при которой тоже возвращается значение 85 - нужно проверять контрольную сумму полученных от датчика данных.
Вы просто не выводите туда 85, тогда и убирать не придётся. Выводите только тогда,когда сенсор начнёт нормальные значения выдавать.
Согласен, это наилучшее решение. Только не пойму, в силу малого опыта в программировании, куда вписать код (а может, убрать). Насколько я понял, в основной программе только 2 команды display (то есть высветить), да и то первая команда только задает яркость индикатора. Было бы куда проще, если бы первая команда выводила на экран результат опроса датчика о состоянии. Тогда можно было бы её закомментировать, и все, проблема была бы решена. В других 2-х файлах команды display нет. Комментарии скупые, о том, что следующий код опрашивает датчик и выводит результат на табло, ни слова нет. В общем, тут я и завис.
Вы просто не выводите туда 85, тогда и убирать не придётся. Выводите только тогда,когда сенсор начнёт нормальные значения выдавать.
Согласен, это наилучшее решение.
Если вы поняли это так, что надо отлавливать значение 85 и не выводить его на дисплей - вы поняли неправильно. Хотя это тоже вариант :) если вы измеряете температуру таких обьектов, у которых 85 гр С маловероятно :)
Ну прочитайте-ж, наконец, документацию !!!!!!!!!!!!!!!!!
POWER-UP STATE означает " состояние после включения питания"
Он ВСЕГДА после подачи питания в первые два регистра САМ прописывает туда 50h и 05h ( 85 градусов )
И 85 там будет лежать до первого запущенного вами преобразования.
Согласен, это наилучшее решение. Только не пойму, в силу малого опыта в программировании, куда вписать код (а может, убрать).
Не выводите ничего, пока не получите результат с нормальной контрольной суммой. Или заставку выведите.
Если вы поняли это так, что надо отлавливать значение 85 и не выводить его на дисплей - вы поняли неправильно. Хотя это тоже вариант :) если вы измеряете температуру таких обьектов, у которых 85 гр С маловероятно :)
Да, именно так, максимум 40 гр. Эти цифры мне нужны были только, чтобы показать, что датчик жив. Если выводит температуру, значит, датчик работает. 85 это уже избыточная информация. А если датчик перестанет показывать температуру, можно тогда раскомментировать строчки, и посмотреть, что за код ошибки датчик показывает. Так что от цифры 85 можно избавляться. Только вот не знаю, как. Просмотрел код TM1637Display.cpp еще раз. Там есть строки
Может, команда writeByte и выводит цифры на дисплей?
Может, команда writeByte и выводит цифры на дисплей?
Так Вы что, ни буквы в этом коде не понимаете?
Так Вы что, ни буквы в этом коде не понимаете?
Кое-что понимаю. Например, for - это цикл, в скобках иницализация, условие и инкремент. writeByte - дословно "Написать байт". Команда может быть для чего угодно, от записи массива в ячейку оперативной памяти до вывода на дисплей индикатора. Но полной уверенности нет, поэтому обращаюсь за помощью к тем, кто понимает определенно.
Понятно.