И вот черт бы с тем, что значение не обнуляется. С этим я разберусь. Опять не чистая строка получается. Вот эти символы в начале портят весь выод на дисплей. Вместо "0700" на дисплее " F07".
Вот сама библиотека, которую я использую для 1650 - tm1650.h
/** ============================================
* 7 segment display driver for JY-MCU module based on TM1650 chip
* Copyright (c) 2015 Anatoli Arkhipenko
*
*
* Changelog:
* v1.0.0:
* 2015-02-24 - Initial release
*
* v1.0.1:
* 2015-04-27 - Added support of program memery (PROGMEM) to store the ASCII to Segment Code table
*
* v1.0.2:
* 2015-08-08 - Added check if panel is connected during init. All calls will be disabled is panel was not connected during init.
*
* v1.1.0:
* 2015-12-20 - code clean up. Moved to a single header file. Added Gradual brightness method
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ===============================================*/
#include <Arduino.h>
#include <Wire.h>
#ifndef _TM1650_H_
#define _TM1650_H_
#define TM1650_USE_PROGMEM
#ifdef TM1650_USE_PROGMEM
#include <avr/pgmspace.h>
#endif
#define TM1650_DISPLAY_BASE 0x34 // Address of the left-most digit
#define TM1650_DCTRL_BASE 0x24 // Address of the control register of the left-most digit
#define TM1650_NUM_DIGITS 16 // max number of digits
#define TM1650_MAX_STRING 128 // number of digits
#define TM1650_BIT_ONOFF 0b00000001
#define TM1650_MSK_ONOFF 0b11111110
#define TM1650_BIT_DOT 0b00000001
#define TM1650_MSK_DOT 0b11110111
#define TM1650_BRIGHT_SHIFT 4
#define TM1650_MSK_BRIGHT 0b10001111
#define TM1650_MIN_BRIGHT 0
#define TM1650_MAX_BRIGHT 7
#ifndef TM1650_USE_PROGMEM
const byte TM1650_CDigits[128] {
#else
const PROGMEM byte TM1650_CDigits[128] {
#endif
//0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10
0x00, 0x82, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x0F, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, // 0x20
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7f, 0x6f, 0x00, 0x00, 0x00, 0x48, 0x00, 0x53, // 0x30
0x00, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x6F, 0x76, 0x06, 0x1E, 0x00, 0x38, 0x00, 0x54, 0x3F, // 0x40
0x73, 0x67, 0x50, 0x6D, 0x78, 0x3E, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x39, 0x00, 0x0F, 0x00, 0x08, // 0x50
0x63, 0x5F, 0x7C, 0x58, 0x5E, 0x7B, 0x71, 0x6F, 0x74, 0x02, 0x1E, 0x00, 0x06, 0x00, 0x54, 0x5C, // 0x60
0x73, 0x67, 0x50, 0x6D, 0x78, 0x1C, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x39, 0x30, 0x0F, 0x00, 0x00 // 0x70
};
class TM1650 {
public:
TM1650(unsigned int aNumDigits = 4);
void init();
void clear();
void displayOn();
void displayOff();
void displayState(bool aState);
void displayString(char *aString);
int displayRunning(char *aString);
int displayRunningShift();
void setBrightness(unsigned int aValue = TM1650_MAX_BRIGHT);
void setBrightnessGradually(unsigned int aValue = TM1650_MAX_BRIGHT);
inline unsigned int getBrightness() { return iBrightness; };
void controlPosition(unsigned int aPos, byte aValue);
void setPosition(unsigned int aPos, byte aValue);
void setDot(unsigned int aPos, bool aState);
byte getPosition(unsigned int aPos) { return iBuffer[aPos]; };
inline unsigned int getNumPositions() { return iNumDigits; };
private:
char *iPosition;
bool iActive;
unsigned int iNumDigits;
unsigned int iBrightness;
char iString[TM1650_MAX_STRING+1];
byte iBuffer[TM1650_NUM_DIGITS+1];
byte iCtrl[TM1650_NUM_DIGITS];
};
// ---- Implementation ----
/** Constructor, uses default values for the parameters
* so could be called with no parameters.
* aNumDigits - number of display digits (default = 4)
*/
TM1650::TM1650(unsigned int aNumDigits) {
iNumDigits = (aNumDigits > TM1650_NUM_DIGITS) ? TM1650_NUM_DIGITS : aNumDigits;
}
/** Initialization
* initializes the driver. Turns display on, but clears all digits.
*/
void TM1650::init() {
iPosition = NULL;
for (int i=0; i<iNumDigits; i++) {
iBuffer[i] = 0;
iCtrl[i] = 0;
}
Wire.beginTransmission(TM1650_DISPLAY_BASE);
iActive = (Wire.endTransmission() == 0);
clear();
displayOn();
}
/** Set brightness of all digits equally
* aValue - brightness value with 1 being the lowest, and 7 being the brightest
*/
void TM1650::setBrightness(unsigned int aValue) {
if (!iActive) return;
iBrightness = (aValue > TM1650_MAX_BRIGHT) ? TM1650_MAX_BRIGHT : aValue;
for (int i=0; i<iNumDigits; i++) {
Wire.beginTransmission(TM1650_DCTRL_BASE+i);
iCtrl[i] = (iCtrl[i] & TM1650_MSK_BRIGHT) | ( iBrightness << TM1650_BRIGHT_SHIFT );
Wire.write((byte) iCtrl[i]);
Wire.endTransmission();
}
}
/** Set brightness of all digits equally
* aValue - brightness value with 1 being the lowest, and 7 being the brightest
*/
void TM1650::setBrightnessGradually(unsigned int aValue) {
if (!iActive || aValue == iBrightness) return;
if (aValue > TM1650_MAX_BRIGHT) aValue = TM1650_MAX_BRIGHT;
int step = (aValue < iBrightness) ? -1 : 1;
unsigned int i = iBrightness;
do {
setBrightness(i);
delay(50);
i += step;
} while (i!=aValue);
}
/** Turns display on or off according to aState
*/
void TM1650::displayState (bool aState)
{
if (aState) displayOn ();
else displayOff();
}
/** Turns the display on
*/
void TM1650::displayOn ()
// turn all digits on
{
if (!iActive) return;
for (int i=0; i<iNumDigits; i++) {
Wire.beginTransmission(TM1650_DCTRL_BASE+i);
iCtrl[i] = (iCtrl[i] & TM1650_MSK_ONOFF) | TM1650_BIT_DOT;
Wire.write((byte) iCtrl[i]);
Wire.endTransmission();
}
}
/** Turns the display off
*/
void TM1650::displayOff ()
// turn all digits off
{
if (!iActive) return;
for (int i=0; i<iNumDigits; i++) {
Wire.beginTransmission(TM1650_DCTRL_BASE+i);
iCtrl[i] = (iCtrl[i] & TM1650_MSK_ONOFF);
Wire.write((byte) iCtrl[i]);
Wire.endTransmission();
}
}
/** Directly write to the CONTROL register of the digital position
* aPos = position to set the control register for
* aValue = value to write to the position
*
* Internal control buffer is updated as well
*/
void TM1650::controlPosition(unsigned int aPos, byte aValue) {
if (!iActive) return;
if (aPos < iNumDigits) {
Wire.beginTransmission(TM1650_DCTRL_BASE + (int) aPos);
iCtrl[aPos] = aValue;
Wire.write(aValue);
Wire.endTransmission();
}
}
/** Directly write to the digit register of the digital position
* aPos = position to set the digit register for
* aValue = value to write to the position
*
* Internal position buffer is updated as well
*/
void TM1650::setPosition(unsigned int aPos, byte aValue) {
if (!iActive) return;
if (aPos < iNumDigits) {
Wire.beginTransmission(TM1650_DISPLAY_BASE + (int) aPos);
iBuffer[aPos] = aValue;
Wire.write(aValue);
Wire.endTransmission();
}
}
/** Directly set/clear a 'dot' next to a specific position
* aPos = position to set/clear the dot for
* aState = display the dot if true, clear if false
*
* Internal buffer is updated as well
*/
void TM1650::setDot(unsigned int aPos, bool aState) {
iBuffer[aPos] = iBuffer[aPos] & 0x7F |(aState ? 0b10000000 : 0);
setPosition(aPos, iBuffer[aPos]);
}
/** Clear all digits. Keep the display on.
*/
void TM1650::clear()
// clears all digits
{
if (!iActive) return;
for (int i=0; i<iNumDigits; i++) {
Wire.beginTransmission(TM1650_DISPLAY_BASE+i);
iBuffer[i] = 0;
Wire.write((byte) 0);
Wire.endTransmission();
}
}
/** Display string on the display
* aString = character array to be displayed
*
* Internal buffer is updated as well
* Only first N positions of the string are displayed if
* the string is longer than the number of digits
*/
void TM1650::displayString(char *aString)
{
if (!iActive) return;
for (int i=0; i<iNumDigits; i++) {
byte a = ((byte) aString[i]) & 0b01111111;
byte dot = ((byte) aString[i]) & 0b10000000;
#ifndef TM1650_USE_PROGMEM
iBuffer[i] = TM1650_CDigits[a];
#else
iBuffer[i] = pgm_read_byte_near(TM1650_CDigits + a);
#endif
if (a) {
Wire.beginTransmission(TM1650_DISPLAY_BASE+i);
Wire.write(iBuffer[i] | dot);
Wire.endTransmission();
}
else
break;
}
}
/** Display string on the display in a running fashion
* aString = character array to be displayed
*
* Starts with first N positions of the string.
* Subsequent characters are displayed with 1 char shift each time displayRunningShift() is called
*
* returns: number of iterations remaining to display the whole string
*/
int TM1650::displayRunning(char *aString) {
strncpy(iString, aString, TM1650_MAX_STRING+1);
iPosition = iString;
iString[TM1650_MAX_STRING] = '\0'; //just in case.
displayString(iPosition);
int l = strlen(iPosition);
if (l <= iNumDigits) return 0;
return (l - iNumDigits);
}
/** Display next segment (shifting to the left) of the string set by displayRunning()
* Starts with first N positions of the string.
* Subsequent characters are displayed with 1 char shift each time displayRunningShift is called
*
* returns: number of iterations remaining to display the whole string
*/
int TM1650::displayRunningShift() {
if (strlen(iPosition) <= iNumDigits) return 0;
displayString(++iPosition);
return (strlen(iPosition) - iNumDigits);
}
#endif /* _TM1650_H_ */
Она совсем коротенькая. Может специалисты увидят причину зависания?
Хотя кажется это я сглупил. Кнопки же этой библиотекой не обрабатываются.
Сейчас пытаюсь еще с sprintf разобраться. my_itoa имеется ввиду не готовая уже стандартная функция, а самому какой-то обработчик написать или найти надо?
Блин, вот наверно я попоясдеревянный! Пытаюсь найти исходники itoa и нихрена! Ведь понимаю, что она в какой-то библиотеке по умолчанию. Не находится. В инете тоже куча примеров, но исходника не нахожу!
Я использую такой вариант, написал для вывода форматированных значений до 256, больше и не нужно обычно:
char * my_utoa(uint8_t j, char* buf, uint8_t dig)
{
char *s;
char *t;
uint8_t i = dig;
s = buf;
do
{
char n = j % 10;
*s++ = '0' + n;
j /= 10;
if (dig == 0)
i = j;
else
i--;
} while (i);
*s-- = 0;
for (t = buf; t < s; )
{
char tmp = *t;
*t++ = *s;
*s-- = tmp;
}
return buf;
}
На входе параметры следующие: uint8_t j - преобразуемое значение, char * buff указатель на буфер, uint8_t dig - количество цифр с 0 в начале, фиксированная длина строки на выходе, если значение не влезает, то старшие разряды теряются. Если dig=0 - то начальных 0 не будет, а длина строки завит от значения.
Если нужно преобразование знакового - то код такой:
char *my_itoa(int8_t val, char* buf, uint8_t dig)
{
char *s;
char *t;
uint8_t i = dig;
uint8_t sign = 0;
uint8_t j = val;
if (val < 0)
{
sign = 1;
j = (uint8_t) - val;
}
s = buf;
do
{
char n = j % 10;
*s++ = '0' + n;
j /= 10;
if (dig == 0)
i = j;
else
i--;
} while (i);
if (sign)
*s++ = '-';
*s-- = 0;
for (t = buf; t < s; )
{
char tmp = *t;
*t++ = *s;
*s-- = tmp;
}
return buf;
}
Тестовый пример для Ардуино ИДЕ (там и функция convert_time_to_char() для ТС):
И вот черт бы с тем, что значение не обнуляется. С этим я разберусь. Опять не чистая строка получается. Вот эти символы в начале портят весь выод на дисплей. Вместо "0700" на дисплее " F07".
Но у меня к сожалению DS1307. И печатная плата уже получена из китая. Да и купить сейчас эту микруху в Алиэкспресс наверное будет стоить дорого в связи с текущими событиями в России.
Ключевое слово тут платы купил в Китае. В общем мне проще плюнуть и включать свет вручную, чем заменить ds1307. И не из-за упрямства, а жалко потраченных денег и ещё столько придётся потратить. Только не предлагайте мне платы вручную развести. Принтера лазерного у меня нет, а рисовать как раньше пером сложновато будет.
Ключевое слово тут платы купил в Китае. В общем мне проще плюнуть и включать свет вручную, чем заменить ds1307. И не из-за упрямства, а жалко потраченных денег и ещё столько придётся потратить. Только не предлагайте мне платы вручную развести. Принтера лазерного у меня нет, а рисовать как раньше пером сложновато будет.
По регистрам они одинаковы, только адреса разные.
Я из DS3231 данные несколькими командами wire вытаскиваю, без всяких библиотек.
Может и одинаковы. Вот только как 16-выводную микросхему впаять на место 8-выводной?
Да оставьте вы DS3107, Проблема не в DS3107, дописывайте свой код.
Согласен. Вот сейчас ищу альтернативу библиотеке IARDUINORTC. Тут предлагали код, его попробую. Правда там без даты. Но в принципе она не сильно нужна. Попробую его сравнить с тем, что сам надергал из библиотек. Ну и ещё несколько библиотек под ds1307. Буду сегодня пробовать.
Может и одинаковы. Вот только как 16-выводную микросхему впаять на место 8-выводной?
Да оставьте вы DS3107, Проблема не в DS3107, дописывайте свой код.
Согласен. Вот сейчас ищу альтернативу библиотеке IARDUINORTC. Тут предлагали код, его попробую. Правда там без даты. Но в принципе она не сильно нужна. Попробую его сравнить с тем, что сам надергал из библиотек. Ну и ещё несколько библиотек под ds1307. Буду сегодня пробовать.
Да не нужна там библиотека если вы wire используете.
Зачем в принципе гонять данные из цифры в ASCII потом опять в цифру. Тем более для Тини.
Умом я это понимаю! Но wire сложновато для меня напрямую. Я уж не говорю о коде, который надо бы использовать для Тини. Я писал один скетч для Тини13. Я там заменил всякие DigitalWrite и т.п. на коды. Но тупо нашел в инете и заменил. Не въезжаю я пока в эти коды! :-( Но надо въезжать. Буду пытаться. Тем более, что пример для работы с DS1307 тут в теме уже выложен.
Вам может и из пустого в порожнее, а мне очень помогли некоторые ответы. Да, воды конечно много. Но, заметте, не от меня.
а от кого? Вода ведь в ветке появляется, потому что вы топчетесь на одном месте. Знаний у вас практически нет. Так и дальше будете каждую строчку на форуме выклянчивать? Работу со строками вам несколько человек обьяснили - вы хоть что-то поняли? - сомневаюсь! больше похоже, что тупо скопировали готовое решение и через пять минут снова все забыли.
Я вам уже на прошлой странице писал, что вы категорически мало знаете. Вам надо отложить свой проект на пару месяцев и засесть за учебники. Разобраться с основами Си, переменными и указателями, работой с массивами, организацию текстовых строк.
А то, что происходит в этой ветке - это онанизм чистой воды. Туда-сюда, туда-сюда без толку. Самокритика дело хорошее, но не пора ли от заявлений "я не знаю массивы char*" перейти все же к изучению? писать каждую строчку в вашем коде за вас никто не будет, пошлют да и все.
Вам может и из пустого в порожнее, а мне очень помогли некоторые ответы. Да, воды конечно много. Но, заметте, не от меня.
а от кого? Вода ведь в ветке появляется, потому что вы топчетесь на одном месте. Знаний у вас практически нет. Так и дальше будете каждую строчку на форуме выклянчивать? Работу со строками вам несколько человек обьяснили - вы хоть что-то поняли? - сомневаюсь! больше похоже, что тупо скопировали готовое решение и через пять минут снова все забыли.
Я вам уже на прошлой странице писал, что вы категорически мало знаете. Вам надо отложить свой проект на пару месяцев и засесть за учебники. Разобраться с основами Си, переменными и указателями, работой с массивами, организацию текстовых строк.
А то, что происходит в этой ветке - это онанизм чистой воды. Туда-сюда, туда-сюда без толку. Самокритика дело хорошее, но не пора ли от заявлений "я не знаю массивы char*" перейти все же к изучению? писать каждую строчку в вашем коде за вас никто не будет, пошлют да и все.
Ну а поработаете за меня наверное вы? Ну пока я буду грызть гранит науки.
Да я мало знаю. Но вот такие литры воды не выплескиваю на форум. Я рад, что ваша деятельность была связана изначально с предметом спора. Но к сожалению на этом форуме часто видишь именно как учат жизни, а не помогают разобраться с материалом. Правда подобных реплик я ждал с начала темы. Странно, что они пришли на 3 странице.
Хотя все. Я замолкаю. Просто не вытерпел. Больше не по теме ни скажу ни слова. Только вопросы и ответы.
Э, нет. Так не пойдет. Возможность поучить новичка жизни - это моя компенсация за помощь на форуме. А если тупо отвечать на вопросы - какой мне тогда интерес вообше ходить в эту ветку? - лучше пойду детектив почитаю...
Э, нет. Так не пойдет. Возможность поучить новичка жизни - это моя компенсация за помощь на форуме. А если тупо отвечать на вопросы - какой мне тогда интерес вообше ходить в эту ветку? - лучше пойду детектив почитаю...
Я конечно жестоко извиняюсь, но сколько вам лет, чтобы ЖИЗНИ учить? За программирование не скажу. Но я со своими 50 с хвостиком жизни сам кого хочешь научу! ;-)
Ну а поработаете за меня наверное вы? Ну пока я буду грызть гранит науки.
не надо лукавить. На то чтоб десяток раз переписывать работу со строками - время нашли, а на учебник нет?
На самом деле для 50-летнего вы какой-то очень наивный. А не приходит в голову, что чтение учебника - это не увеличение траты времени, а ее сокращение?
Если разберетесь в языке - потом будете щелкать все свои вопросы в пять минут и вообще без форума.
Мне осенью стукнет столько же. Ну вот и смотрите. Мой програамерский опыт - лет пять писания баз данных на Delphy в глубокой молодости. Ну и Powershell сейчас использую в рамках должностных обязанностей. Тка что видите, поверхностный знания есть. Но вот въезжать в С и более глубокие языки тяжеловато. Уж очень велико различие в рабо с переменными, тем более строковыми! Но я честно стараюсь и даже из этой темы очень много почерпнул!
Ну а поработаете за меня наверное вы? Ну пока я буду грызть гранит науки.
не надо лукавить. На то чтоб десяток раз переписывать работу со строками - время нашли, а на учебник нет?
На самом деле для 50-летнего вы какой-то очень наивный. А не приходит в голову, что чтение учебника - это не увеличение траты времени, а ее сокращение?
Если разберетесь в языке - потом будете щелкать все свои вопросы в пять минут и вообще без форума.
Десяток строк накидать и нажать компиляцию - это 10 минут. Я это в перерывах между исполнением должностных обязанностей делаю. Учебник же читать - надо вникать. Иначе страницу прочитал, потом часок поработал и уже снова эту страницу перечитывать надо. Тем боле, что с азов надо осваивать. Вы то должны понимать чем отличается учебник от краткой инструкции.
Десяток строк накидать и нажать компиляцию - это 10 минут. Я это в перерывах между исполнением должностных обязанностей делаю. Учебник же читать - надо вникать. Иначе страницу прочитал, потом часок поработал и уже снова эту страницу перечитывать надо. Тем боле, что с азов надо осваивать. Вы то должны понимать чем отличается учебник от краткой инструкции.
Не надо себя жалеть. Ничего смертельного в учебниках нет. Я сам лет 15 писал на дельфи. Когда пришел сюда, поначалу от синтаксиса зубы болели. Да и сейчас от некоторых вольностей глаза на лоб лезут. Тем не менее освоился.
На самом деле разница между языками не так важна. Важнее разница в подходе между программированием для ПК и для МК. Тут размашистые жесты типа int вместо byte и string везде, где только вздумается, не прокатывают. Если только задачка крохотная ))
ЗЫ: не нужны строки для вывода времени на семисегментник ;)
На самом деле разница между языками не так важна. Важнее разница в подходе между программированием для ПК и для МК. Тут размашистые жесты типа int вместо byte и string везде, где только вздумается, не прокатывают. Если только задачка крохотная ))
Думаю паскаль был самым строгим языком программирования из высокоуровневых. Из низкоуровневых, пожалуй, только ассемблер можно отнести к таковым. Ну а С всё же подемократичнее, и наверно по этому, можно иногда увидеть неожиданные результаты )
Думаю паскаль был самым строгим языком программирования из высокоуровневых.
Да, ладно, там демократии выше крыши - например, неявные преобразования типов там вполне себе присутствуют. Вы, наверное, просто не знаете языков, где строгость просто на уровне паранойи.
если разобраться с библиотекой, можно и напрямую выводить числа.
конечно можно
В библиотеке есть метод setPosition() который позволяет вывести заданный символ в заданную позицию дисплея.
Вывести этим методом цифру в нужную позицию - это одна строчка:
setPosition(pos, digit + '0');
где pos - это позиция на индикаторе, а digit - цифрв от 0 до 9 (не символ. а именно целое типа uint8_t)
UPD - нет, немного сложнее... нужно еще добавить чтение кода цифры из массива в пргмем. Его можно взять из процедуры вывода строки.
Тем не менее написать прямой вывод цифр на индикатор для этой либы - это вопрос 10 минут и пяти строчек кода.
А разве setPosition не к выводу точки относится? В программе используется displayString(char *aString). Там вроде тоже почти понятно. Перебирает массив, переданный в нее. Вот только TM1650_CDigits я никак не пойму. 4 разряда по 8 (если считать точку) сегментов. Принцип не понимаю!
лучше сделать как в той же itoa, где результат работы внутри параметров, передаваемых в функцию!
это не "лучше", а почитай единственный метод получения результатов работы функций, работающих со строками
Все равно что-то не так.
Вот что получается. Это в мониторе порта
Ну и соответственно вот что имеем. Сама функция:
void convert_time_to_char(byte val1, byte val2, byte prop, char out[5]){ char x1[2], x2[2],y1[2],y2[2]; itoa(val1/10, x1, 10); itoa(val1%10, x2, 10); itoa(val2/10, y1, 10); itoa(val2%10, y2, 10); strcat(out, x1); strcat(out, x2); strcat(out, y1); strcat(out, y2); switch (prop){ case 1: out[0] = ' '; out[1] = ' '; break; case 2: out[2] = ' '; out[3] = ' '; break; } Serial.println(out); }И вот ее вызов:
case 3: char out_on[5]; VAR_ON_MIN = eeprom_read_word(0); VAR_ON_HOUR = eeprom_read_word(4); convert_time_to_char(VAR_ON_HOUR, VAR_ON_MIN, 0, out_on); Serial.println(out_on); d.displayString(out_on); d.setDot(1, true); break;И вот черт бы с тем, что значение не обнуляется. С этим я разберусь. Опять не чистая строка получается. Вот эти символы в начале портят весь выод на дисплей. Вместо "0700" на дисплее " F07".
Что у Вас написано в строке №15 в #68?
if (display_mode < 5) display_mode == 4?display_mode = 0:display_mode++; else { ...Можете пояснить?
Я тоже долго смотрел на это, использование - очень не стандартное, но работать должно.
Получилось. Пришлось обнулять переменную. Сама она почему-то не обнуляется.
case 3: char out_on[5]; out_on[0] = (char)0; VAR_ON_MIN = eeprom_read_word(0); VAR_ON_HOUR = eeprom_read_word(4); convert_time_to_char(VAR_ON_HOUR, VAR_ON_MIN, 0, out_on); Serial.println(out_on); d.displayString(out_on); d.setDot(1, true); break;неправильно параметры функции описали
void convert_time_to_char(byte val1, byte val2, byte prop, char out[5]){массив нельзя передать как параметр
И да, переменная и не должна обнулятся - с чего бы?
Вот так правильно? Вроде тоже работает.
И все-таки остается у меня главный вопрос. Зависает собака, если даже добавить в код строку
Без нее работает без проблем.
Вот сама библиотека, которую я использую для 1650 - tm1650.h
/** ============================================ * 7 segment display driver for JY-MCU module based on TM1650 chip * Copyright (c) 2015 Anatoli Arkhipenko * * * Changelog: * v1.0.0: * 2015-02-24 - Initial release * * v1.0.1: * 2015-04-27 - Added support of program memery (PROGMEM) to store the ASCII to Segment Code table * * v1.0.2: * 2015-08-08 - Added check if panel is connected during init. All calls will be disabled is panel was not connected during init. * * v1.1.0: * 2015-12-20 - code clean up. Moved to a single header file. Added Gradual brightness method * * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * ===============================================*/ #include <Arduino.h> #include <Wire.h> #ifndef _TM1650_H_ #define _TM1650_H_ #define TM1650_USE_PROGMEM #ifdef TM1650_USE_PROGMEM #include <avr/pgmspace.h> #endif #define TM1650_DISPLAY_BASE 0x34 // Address of the left-most digit #define TM1650_DCTRL_BASE 0x24 // Address of the control register of the left-most digit #define TM1650_NUM_DIGITS 16 // max number of digits #define TM1650_MAX_STRING 128 // number of digits #define TM1650_BIT_ONOFF 0b00000001 #define TM1650_MSK_ONOFF 0b11111110 #define TM1650_BIT_DOT 0b00000001 #define TM1650_MSK_DOT 0b11110111 #define TM1650_BRIGHT_SHIFT 4 #define TM1650_MSK_BRIGHT 0b10001111 #define TM1650_MIN_BRIGHT 0 #define TM1650_MAX_BRIGHT 7 #ifndef TM1650_USE_PROGMEM const byte TM1650_CDigits[128] { #else const PROGMEM byte TM1650_CDigits[128] { #endif //0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 0x00, 0x82, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x0F, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, // 0x20 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7f, 0x6f, 0x00, 0x00, 0x00, 0x48, 0x00, 0x53, // 0x30 0x00, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x6F, 0x76, 0x06, 0x1E, 0x00, 0x38, 0x00, 0x54, 0x3F, // 0x40 0x73, 0x67, 0x50, 0x6D, 0x78, 0x3E, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x39, 0x00, 0x0F, 0x00, 0x08, // 0x50 0x63, 0x5F, 0x7C, 0x58, 0x5E, 0x7B, 0x71, 0x6F, 0x74, 0x02, 0x1E, 0x00, 0x06, 0x00, 0x54, 0x5C, // 0x60 0x73, 0x67, 0x50, 0x6D, 0x78, 0x1C, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x39, 0x30, 0x0F, 0x00, 0x00 // 0x70 }; class TM1650 { public: TM1650(unsigned int aNumDigits = 4); void init(); void clear(); void displayOn(); void displayOff(); void displayState(bool aState); void displayString(char *aString); int displayRunning(char *aString); int displayRunningShift(); void setBrightness(unsigned int aValue = TM1650_MAX_BRIGHT); void setBrightnessGradually(unsigned int aValue = TM1650_MAX_BRIGHT); inline unsigned int getBrightness() { return iBrightness; }; void controlPosition(unsigned int aPos, byte aValue); void setPosition(unsigned int aPos, byte aValue); void setDot(unsigned int aPos, bool aState); byte getPosition(unsigned int aPos) { return iBuffer[aPos]; }; inline unsigned int getNumPositions() { return iNumDigits; }; private: char *iPosition; bool iActive; unsigned int iNumDigits; unsigned int iBrightness; char iString[TM1650_MAX_STRING+1]; byte iBuffer[TM1650_NUM_DIGITS+1]; byte iCtrl[TM1650_NUM_DIGITS]; }; // ---- Implementation ---- /** Constructor, uses default values for the parameters * so could be called with no parameters. * aNumDigits - number of display digits (default = 4) */ TM1650::TM1650(unsigned int aNumDigits) { iNumDigits = (aNumDigits > TM1650_NUM_DIGITS) ? TM1650_NUM_DIGITS : aNumDigits; } /** Initialization * initializes the driver. Turns display on, but clears all digits. */ void TM1650::init() { iPosition = NULL; for (int i=0; i<iNumDigits; i++) { iBuffer[i] = 0; iCtrl[i] = 0; } Wire.beginTransmission(TM1650_DISPLAY_BASE); iActive = (Wire.endTransmission() == 0); clear(); displayOn(); } /** Set brightness of all digits equally * aValue - brightness value with 1 being the lowest, and 7 being the brightest */ void TM1650::setBrightness(unsigned int aValue) { if (!iActive) return; iBrightness = (aValue > TM1650_MAX_BRIGHT) ? TM1650_MAX_BRIGHT : aValue; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DCTRL_BASE+i); iCtrl[i] = (iCtrl[i] & TM1650_MSK_BRIGHT) | ( iBrightness << TM1650_BRIGHT_SHIFT ); Wire.write((byte) iCtrl[i]); Wire.endTransmission(); } } /** Set brightness of all digits equally * aValue - brightness value with 1 being the lowest, and 7 being the brightest */ void TM1650::setBrightnessGradually(unsigned int aValue) { if (!iActive || aValue == iBrightness) return; if (aValue > TM1650_MAX_BRIGHT) aValue = TM1650_MAX_BRIGHT; int step = (aValue < iBrightness) ? -1 : 1; unsigned int i = iBrightness; do { setBrightness(i); delay(50); i += step; } while (i!=aValue); } /** Turns display on or off according to aState */ void TM1650::displayState (bool aState) { if (aState) displayOn (); else displayOff(); } /** Turns the display on */ void TM1650::displayOn () // turn all digits on { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DCTRL_BASE+i); iCtrl[i] = (iCtrl[i] & TM1650_MSK_ONOFF) | TM1650_BIT_DOT; Wire.write((byte) iCtrl[i]); Wire.endTransmission(); } } /** Turns the display off */ void TM1650::displayOff () // turn all digits off { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DCTRL_BASE+i); iCtrl[i] = (iCtrl[i] & TM1650_MSK_ONOFF); Wire.write((byte) iCtrl[i]); Wire.endTransmission(); } } /** Directly write to the CONTROL register of the digital position * aPos = position to set the control register for * aValue = value to write to the position * * Internal control buffer is updated as well */ void TM1650::controlPosition(unsigned int aPos, byte aValue) { if (!iActive) return; if (aPos < iNumDigits) { Wire.beginTransmission(TM1650_DCTRL_BASE + (int) aPos); iCtrl[aPos] = aValue; Wire.write(aValue); Wire.endTransmission(); } } /** Directly write to the digit register of the digital position * aPos = position to set the digit register for * aValue = value to write to the position * * Internal position buffer is updated as well */ void TM1650::setPosition(unsigned int aPos, byte aValue) { if (!iActive) return; if (aPos < iNumDigits) { Wire.beginTransmission(TM1650_DISPLAY_BASE + (int) aPos); iBuffer[aPos] = aValue; Wire.write(aValue); Wire.endTransmission(); } } /** Directly set/clear a 'dot' next to a specific position * aPos = position to set/clear the dot for * aState = display the dot if true, clear if false * * Internal buffer is updated as well */ void TM1650::setDot(unsigned int aPos, bool aState) { iBuffer[aPos] = iBuffer[aPos] & 0x7F |(aState ? 0b10000000 : 0); setPosition(aPos, iBuffer[aPos]); } /** Clear all digits. Keep the display on. */ void TM1650::clear() // clears all digits { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DISPLAY_BASE+i); iBuffer[i] = 0; Wire.write((byte) 0); Wire.endTransmission(); } } /** Display string on the display * aString = character array to be displayed * * Internal buffer is updated as well * Only first N positions of the string are displayed if * the string is longer than the number of digits */ void TM1650::displayString(char *aString) { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { byte a = ((byte) aString[i]) & 0b01111111; byte dot = ((byte) aString[i]) & 0b10000000; #ifndef TM1650_USE_PROGMEM iBuffer[i] = TM1650_CDigits[a]; #else iBuffer[i] = pgm_read_byte_near(TM1650_CDigits + a); #endif if (a) { Wire.beginTransmission(TM1650_DISPLAY_BASE+i); Wire.write(iBuffer[i] | dot); Wire.endTransmission(); } else break; } } /** Display string on the display in a running fashion * aString = character array to be displayed * * Starts with first N positions of the string. * Subsequent characters are displayed with 1 char shift each time displayRunningShift() is called * * returns: number of iterations remaining to display the whole string */ int TM1650::displayRunning(char *aString) { strncpy(iString, aString, TM1650_MAX_STRING+1); iPosition = iString; iString[TM1650_MAX_STRING] = '\0'; //just in case. displayString(iPosition); int l = strlen(iPosition); if (l <= iNumDigits) return 0; return (l - iNumDigits); } /** Display next segment (shifting to the left) of the string set by displayRunning() * Starts with first N positions of the string. * Subsequent characters are displayed with 1 char shift each time displayRunningShift is called * * returns: number of iterations remaining to display the whole string */ int TM1650::displayRunningShift() { if (strlen(iPosition) <= iNumDigits) return 0; displayString(++iPosition); return (strlen(iPosition) - iNumDigits); } #endif /* _TM1650_H_ */Она совсем коротенькая. Может специалисты увидят причину зависания?
Хотя кажется это я сглупил. Кнопки же этой библиотекой не обрабатываются.
неправильно параметры функции описали
void convert_time_to_char(byte val1, byte val2, byte prop, char out[5]){массив нельзя передать как параметр
Почему? Клапа запретил?
нет, ТС, то, понятно, что нельзя - он себе на одно место этим столько огребёт, а так-то ... пожалуйста
int kaka[] = {1, 2, 3, 4, 5}; void prnt(int arr[5]) { for (int i = 0; i < 5; i++) { Serial.print(arr[i]); Serial.print(' '); } Serial.println(); } void setup(void) { Serial.begin(9600); prnt (kaka); } void loop(void) {}А может кто посоветует проверенную библиотеку под RTC? Попробовать часы на другой библиотеке сделать. МОжет тогда зависать не будет?
Блин, вот наверно я попоясдеревянный! Пытаюсь найти исходники itoa и нихрена! Ведь понимаю, что она в какой-то библиотеке по умолчанию. Не находится. В инете тоже куча примеров, но исходника не нахожу!
Я использую такой вариант, написал для вывода форматированных значений до 256, больше и не нужно обычно:
char * my_utoa(uint8_t j, char* buf, uint8_t dig) { char *s; char *t; uint8_t i = dig; s = buf; do { char n = j % 10; *s++ = '0' + n; j /= 10; if (dig == 0) i = j; else i--; } while (i); *s-- = 0; for (t = buf; t < s; ) { char tmp = *t; *t++ = *s; *s-- = tmp; } return buf; }На входе параметры следующие: uint8_t j - преобразуемое значение, char * buff указатель на буфер, uint8_t dig - количество цифр с 0 в начале, фиксированная длина строки на выходе, если значение не влезает, то старшие разряды теряются. Если dig=0 - то начальных 0 не будет, а длина строки завит от значения.
Если нужно преобразование знакового - то код такой:
char *my_itoa(int8_t val, char* buf, uint8_t dig) { char *s; char *t; uint8_t i = dig; uint8_t sign = 0; uint8_t j = val; if (val < 0) { sign = 1; j = (uint8_t) - val; } s = buf; do { char n = j % 10; *s++ = '0' + n; j /= 10; if (dig == 0) i = j; else i--; } while (i); if (sign) *s++ = '-'; *s-- = 0; for (t = buf; t < s; ) { char tmp = *t; *t++ = *s; *s-- = tmp; } return buf; }Тестовый пример для Ардуино ИДЕ (там и функция convert_time_to_char() для ТС):
char *my_itoa(int8_t val, char* buf, uint8_t dig) { char *s; char *t; uint8_t i = dig; uint8_t sign = 0; uint8_t j = val; if (val < 0) { sign = 1; j = (uint8_t) - val; } s = buf; do { char n = j % 10; *s++ = '0' + n; j /= 10; if (dig == 0) i = j; else i--; } while (i); if (sign) *s++ = '-'; *s-- = 0; for (t = buf; t < s; ) { char tmp = *t; *t++ = *s; *s-- = tmp; } return buf; } char *my_utoa(uint8_t j, char* buf, uint8_t dig) { char *s; char *t; uint8_t i = dig; s = buf; do { char n = j % 10; *s++ = '0' + n; j /= 10; if (dig == 0) i = j; else i--; } while (i); *s-- = 0; for (t = buf; t < s; ) { char tmp = *t; *t++ = *s; *s-- = tmp; } return buf; } char * convert_time_to_char(byte val1, byte val2, byte prop, char *buff) { my_utoa(val1, buff, 2); my_utoa(val2, buff+2, 2); switch (prop){ case 1: buff[0] = ' '; buff[1] = ' '; break; case 2: buff[2] = ' '; buff[3] = ' '; break; } return buff; } void setup() { char buff[5]; Serial.begin(115200); int8_t value = 0; Serial.print("print \tmy_itoa\tmy_utoa\t itoa\n\n"); do { Serial.print(value); my_itoa(value, buff, 3); Serial.print("\t|"); Serial.print(buff); Serial.print("|\t"); my_utoa((uint8_t)value, buff, 3); Serial.print("|"); Serial.print(buff); Serial.print("|\t"); itoa(value, buff, 10); Serial.print("|"); Serial.print(buff); Serial.println("|"); value++; } while (value != 0); my_utoa(12, buff, 2); my_utoa( 5, buff+2, 2); Serial.print("\n Время 1: "); Serial.print(buff); Serial.println(";"); my_utoa( 5, buff, 2); my_utoa(12, buff+2, 2); buff[2] = ' '; buff[3] = ' '; Serial.print("\n Время 2: "); Serial.print(buff); Serial.println(";"); Serial.print("\n Строка 1: "); Serial.print(convert_time_to_char(4,10,0,buff)); Serial.println(";"); Serial.print("\n Строка 2: "); Serial.print(convert_time_to_char(4,10,1,buff)); Serial.println(";"); Serial.print("\n Строка 3: "); Serial.print(convert_time_to_char(4,10,2,buff)); Serial.println(";"); } void loop() { // put your main code here, to run repeatedly: }Вывод будет таким:
Табуляция немного съехала в браузере, но, в принципе, идея понятна.
Сама функция:
void convert_time_to_char(byte val1, byte val2, byte prop, char out[5]){ char x1[2], x2[2],y1[2],y2[2]; itoa(val1/10, x1, 10); itoa(val1%10, x2, 10); itoa(val2/10, y1, 10); itoa(val2%10, y2, 10); strcat(out, x1); strcat(out, x2); strcat(out, y1); strcat(out, y2); switch (prop){ case 1: out[0] = ' '; out[1] = ' '; break; case 2: out[2] = ' '; out[3] = ' '; break; } Serial.println(out); }И вот черт бы с тем, что значение не обнуляется. С этим я разберусь. Опять не чистая строка получается. Вот эти символы в начале портят весь выод на дисплей. Вместо "0700" на дисплее " F07".
Как вариант замены:
char *my_utoa(uint8_t j, char* buf, uint8_t dig) { char *s; char *t; uint8_t i = dig; s = buf; do { char n = j % 10; *s++ = '0' + n; j /= 10; if (dig == 0) i = j; else i--; } while (i); *s-- = 0; for (t = buf; t < s; ) { char tmp = *t; *t++ = *s; *s-- = tmp; } return buf; } char * convert_time_to_char(byte val1, byte val2, byte prop, char *buff) { my_utoa(val1, buff, 2); my_utoa(val2, buff+2, 2); switch (prop){ case 1: buff[0] = ' '; buff[1] = ' '; break; case 2: buff[2] = ' '; buff[3] = ' '; break; } return buff; }Описание, код и пример работы - в предыдущем посте.
А может кто посоветует проверенную библиотеку под RTC? Попробовать часы на другой библиотеке сделать. МОжет тогда зависать не будет?
https://github.com/NorthernWidget/DS3231
Проверена. Работает
А может кто посоветует проверенную библиотеку под RTC? Попробовать часы на другой библиотеке сделать. МОжет тогда зависать не будет?
https://github.com/NorthernWidget/DS3231
Проверена. Работает
Но у меня к сожалению DS1307. И печатная плата уже получена из китая. Да и купить сейчас эту микруху в Алиэкспресс наверное будет стоить дорого в связи с текущими событиями в России.
Как для хобби - приемлемо (хотя я там же брал с бесплатной доставкой за 159р): https://aliexpress.ru/item/1005003514093522.html
Как для хобби - приемлемо (хотя я там же брал с бесплатной доставкой за 159р): https://aliexpress.ru/item/1005003514093522.html
Ключевое слово тут платы купил в Китае. В общем мне проще плюнуть и включать свет вручную, чем заменить ds1307. И не из-за упрямства, а жалко потраченных денег и ещё столько придётся потратить. Только не предлагайте мне платы вручную развести. Принтера лазерного у меня нет, а рисовать как раньше пером сложновато будет.
Как для хобби - приемлемо (хотя я там же брал с бесплатной доставкой за 159р): https://aliexpress.ru/item/1005003514093522.html
По регистрам они одинаковы, только адреса разные.
Я из DS3231 данные несколькими командами wire вытаскиваю, без всяких библиотек.
Время туда 1 раз закинул, лет 5 назад.
Может и одинаковы. Вот только как 16-выводную микросхему впаять на место 8-выводной?
Да оставьте вы DS3107, Проблема не в DS3107, дописывайте свой код.
Да оставьте вы DS3107, Проблема не в DS3107, дописывайте свой код.
Согласен. Вот сейчас ищу альтернативу библиотеке IARDUINORTC. Тут предлагали код, его попробую. Правда там без даты. Но в принципе она не сильно нужна. Попробую его сравнить с тем, что сам надергал из библиотек. Ну и ещё несколько библиотек под ds1307. Буду сегодня пробовать.
Да оставьте вы DS3107, Проблема не в DS3107, дописывайте свой код.
Да не нужна там библиотека если вы wire используете.
Зачем в принципе гонять данные из цифры в ASCII потом опять в цифру. Тем более для Тини.
Умом я это понимаю! Но wire сложновато для меня напрямую. Я уж не говорю о коде, который надо бы использовать для Тини. Я писал один скетч для Тини13. Я там заменил всякие DigitalWrite и т.п. на коды. Но тупо нашел в инете и заменил. Не въезжаю я пока в эти коды! :-( Но надо въезжать. Буду пытаться. Тем более, что пример для работы с DS1307 тут в теме уже выложен.
На форуме меньше сидеть надо. 3 страницы из пустого в порожнее.
На форуме меньше сидеть надо. 3 страницы из пустого в порожнее.
Вам может и из пустого в порожнее, а мне очень помогли некоторые ответы. Да, воды конечно много. Но, заметте, не от меня.
Кто ж вас , болезных, заставляет использовать за место нормальных библиотек , всяческие поделия а-ля гивер или iarduino ?
https://github.com/PaulStoffregen/DS1307RTC
Сколько пользуюсь проблем не было ниразу
Вам может и из пустого в порожнее, а мне очень помогли некоторые ответы. Да, воды конечно много. Но, заметте, не от меня.
а от кого? Вода ведь в ветке появляется, потому что вы топчетесь на одном месте. Знаний у вас практически нет. Так и дальше будете каждую строчку на форуме выклянчивать? Работу со строками вам несколько человек обьяснили - вы хоть что-то поняли? - сомневаюсь! больше похоже, что тупо скопировали готовое решение и через пять минут снова все забыли.
Я вам уже на прошлой странице писал, что вы категорически мало знаете. Вам надо отложить свой проект на пару месяцев и засесть за учебники. Разобраться с основами Си, переменными и указателями, работой с массивами, организацию текстовых строк.
А то, что происходит в этой ветке - это онанизм чистой воды. Туда-сюда, туда-сюда без толку. Самокритика дело хорошее, но не пора ли от заявлений "я не знаю массивы char*" перейти все же к изучению? писать каждую строчку в вашем коде за вас никто не будет, пошлют да и все.
Самое смешное, что строки здесь вообще не нужны - чтобы вывести цифры на семисегментный-то индикатор. Тем более в тиньке
Вам может и из пустого в порожнее, а мне очень помогли некоторые ответы. Да, воды конечно много. Но, заметте, не от меня.
а от кого? Вода ведь в ветке появляется, потому что вы топчетесь на одном месте. Знаний у вас практически нет. Так и дальше будете каждую строчку на форуме выклянчивать? Работу со строками вам несколько человек обьяснили - вы хоть что-то поняли? - сомневаюсь! больше похоже, что тупо скопировали готовое решение и через пять минут снова все забыли.
Я вам уже на прошлой странице писал, что вы категорически мало знаете. Вам надо отложить свой проект на пару месяцев и засесть за учебники. Разобраться с основами Си, переменными и указателями, работой с массивами, организацию текстовых строк.
А то, что происходит в этой ветке - это онанизм чистой воды. Туда-сюда, туда-сюда без толку. Самокритика дело хорошее, но не пора ли от заявлений "я не знаю массивы char*" перейти все же к изучению? писать каждую строчку в вашем коде за вас никто не будет, пошлют да и все.
Ну а поработаете за меня наверное вы? Ну пока я буду грызть гранит науки.
Да я мало знаю. Но вот такие литры воды не выплескиваю на форум. Я рад, что ваша деятельность была связана изначально с предметом спора. Но к сожалению на этом форуме часто видишь именно как учат жизни, а не помогают разобраться с материалом. Правда подобных реплик я ждал с начала темы. Странно, что они пришли на 3 странице.
Хотя все. Я замолкаю. Просто не вытерпел. Больше не по теме ни скажу ни слова. Только вопросы и ответы.
Только вопросы и ответы.
Э, нет. Так не пойдет. Возможность поучить новичка жизни - это моя компенсация за помощь на форуме. А если тупо отвечать на вопросы - какой мне тогда интерес вообше ходить в эту ветку? - лучше пойду детектив почитаю...
Библиотеку из #124 то пробовал?
Только вопросы и ответы.
Э, нет. Так не пойдет. Возможность поучить новичка жизни - это моя компенсация за помощь на форуме. А если тупо отвечать на вопросы - какой мне тогда интерес вообше ходить в эту ветку? - лучше пойду детектив почитаю...
Я конечно жестоко извиняюсь, но сколько вам лет, чтобы ЖИЗНИ учить? За программирование не скажу. Но я со своими 50 с хвостиком жизни сам кого хочешь научу! ;-)
Но я со своими 50 с хвостиком жизни сам кого хочешь научу! ;-)
Да тут 80% постоянных пользователей за 50 с хвостиком и старше )))
Библиотеку из #124 то пробовал?
Сегодня буду пробовать. С работой пока разгребаюсь.
не смотрите на то, что мы тут все молоды душой :) - на самом деле тут тех, кто моложе 40- пара человек, остальные 40, 50 и старше. Мне 52
Ну и на этом можно пока стопорнуться. И так тему заср#ли...
Ну а поработаете за меня наверное вы? Ну пока я буду грызть гранит науки.
не надо лукавить. На то чтоб десяток раз переписывать работу со строками - время нашли, а на учебник нет?
На самом деле для 50-летнего вы какой-то очень наивный. А не приходит в голову, что чтение учебника - это не увеличение траты времени, а ее сокращение?
Если разберетесь в языке - потом будете щелкать все свои вопросы в пять минут и вообще без форума.
Ну и на этом можно пока стопорнуться. И так тему заср#ли...
Эта тема ни для чего другого и не годится уже....
Мне осенью стукнет столько же. Ну вот и смотрите. Мой програамерский опыт - лет пять писания баз данных на Delphy в глубокой молодости. Ну и Powershell сейчас использую в рамках должностных обязанностей. Тка что видите, поверхностный знания есть. Но вот въезжать в С и более глубокие языки тяжеловато. Уж очень велико различие в рабо с переменными, тем более строковыми! Но я честно стараюсь и даже из этой темы очень много почерпнул!
Ну а поработаете за меня наверное вы? Ну пока я буду грызть гранит науки.
не надо лукавить. На то чтоб десяток раз переписывать работу со строками - время нашли, а на учебник нет?
На самом деле для 50-летнего вы какой-то очень наивный. А не приходит в голову, что чтение учебника - это не увеличение траты времени, а ее сокращение?
Если разберетесь в языке - потом будете щелкать все свои вопросы в пять минут и вообще без форума.
Десяток строк накидать и нажать компиляцию - это 10 минут. Я это в перерывах между исполнением должностных обязанностей делаю. Учебник же читать - надо вникать. Иначе страницу прочитал, потом часок поработал и уже снова эту страницу перечитывать надо. Тем боле, что с азов надо осваивать. Вы то должны понимать чем отличается учебник от краткой инструкции.
Ладно все. Действительно хватит воды.
Десяток строк накидать и нажать компиляцию - это 10 минут. Я это в перерывах между исполнением должностных обязанностей делаю. Учебник же читать - надо вникать. Иначе страницу прочитал, потом часок поработал и уже снова эту страницу перечитывать надо. Тем боле, что с азов надо осваивать. Вы то должны понимать чем отличается учебник от краткой инструкции.
Не надо себя жалеть. Ничего смертельного в учебниках нет. Я сам лет 15 писал на дельфи. Когда пришел сюда, поначалу от синтаксиса зубы болели. Да и сейчас от некоторых вольностей глаза на лоб лезут. Тем не менее освоился.
На самом деле разница между языками не так важна. Важнее разница в подходе между программированием для ПК и для МК. Тут размашистые жесты типа int вместо byte и string везде, где только вздумается, не прокатывают. Если только задачка крохотная ))
ЗЫ: не нужны строки для вывода времени на семисегментник ;)
ЗЫ: не нужны строки для вывода времени на семисегментник ;)
Вполне соглашусь с этим. Но так написана библиотека для 1650. Возможно, если разобраться с библиотекой, можно и напрямую выводить числа.
Вот вроде бы адекватная либа для ТМ1650: https://github.com/mozgy/Mozz_TM1650
если разобраться с библиотекой, можно и напрямую выводить числа.
конечно можно
В библиотеке есть метод setPosition() который позволяет вывести заданный символ в заданную позицию дисплея.
Вывести этим методом цифру в нужную позицию - это одна строчка:
где pos - это позиция на индикаторе, а digit - цифрв от 0 до 9 (не символ. а именно целое типа uint8_t)
UPD - нет, немного сложнее... нужно еще добавить чтение кода цифры из массива в пргмем. Его можно взять из процедуры вывода строки.
Тем не менее написать прямой вывод цифр на индикатор для этой либы - это вопрос 10 минут и пяти строчек кода.
Я вам подскажу.
Цифра 0 представлена глифом '0', ASCII-код 48. Цифра 9 представлена глифом '9', ASCII-код 57. '9' => 48+9 или '0' + 9. Понимаете логику?
Число 90 представлено строкой "90" или массивом ['9', '0', 0x00].
Т.е. достаточно в ячейку [0] положить ASCII-код 57, а в ячейку [1] - ASCII-код 48.
В числе десятки от единиц сумеете отделить? Их ASCII-коды вычислить смогёте? В нужную ячейку каждый код запихнете?
если разобраться с библиотекой, можно и напрямую выводить числа.
конечно можно
В библиотеке есть метод setPosition() который позволяет вывести заданный символ в заданную позицию дисплея.
Вывести этим методом цифру в нужную позицию - это одна строчка:
где pos - это позиция на индикаторе, а digit - цифрв от 0 до 9 (не символ. а именно целое типа uint8_t)
UPD - нет, немного сложнее... нужно еще добавить чтение кода цифры из массива в пргмем. Его можно взять из процедуры вывода строки.
Тем не менее написать прямой вывод цифр на индикатор для этой либы - это вопрос 10 минут и пяти строчек кода.
Спасибо за совет! Сейчас посмотрю.
На самом деле разница между языками не так важна. Важнее разница в подходе между программированием для ПК и для МК. Тут размашистые жесты типа int вместо byte и string везде, где только вздумается, не прокатывают. Если только задачка крохотная ))
Думаю паскаль был самым строгим языком программирования из высокоуровневых. Из низкоуровневых, пожалуй, только ассемблер можно отнести к таковым. Ну а С всё же подемократичнее, и наверно по этому, можно иногда увидеть неожиданные результаты )
Думаю паскаль был самым строгим языком программирования из высокоуровневых.
Да, ладно, там демократии выше крыши - например, неявные преобразования типов там вполне себе присутствуют. Вы, наверное, просто не знаете языков, где строгость просто на уровне паранойи.
Один "absolute" чего стОит, даже парица не надо с преобразованием.
Возможно
если разобраться с библиотекой, можно и напрямую выводить числа.
конечно можно
В библиотеке есть метод setPosition() который позволяет вывести заданный символ в заданную позицию дисплея.
Вывести этим методом цифру в нужную позицию - это одна строчка:
где pos - это позиция на индикаторе, а digit - цифрв от 0 до 9 (не символ. а именно целое типа uint8_t)
UPD - нет, немного сложнее... нужно еще добавить чтение кода цифры из массива в пргмем. Его можно взять из процедуры вывода строки.
Тем не менее написать прямой вывод цифр на индикатор для этой либы - это вопрос 10 минут и пяти строчек кода.
А разве setPosition не к выводу точки относится? В программе используется displayString(char *aString). Там вроде тоже почти понятно. Перебирает массив, переданный в нее. Вот только TM1650_CDigits я никак не пойму. 4 разряда по 8 (если считать точку) сегментов. Принцип не понимаю!
Ну чтож. Кажется проблему зависания решил. http://arduino.ru/forum/programmirovanie/posovetuite-biblioteku-dlya-ds1307 вот здесь предлагали код вместо библиотеки. Его задействовал и виснуть перестало.