Мои проекты на Ардуино

Контроллеры, драйверы, датчики, управляющие устройства.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Мои проекты на Ардуино

Сообщение aftaev »

Буду выкладывать то что сделал на Ардуино. Изучаю Си и привыкаю к синтаксису языка.
Потому буду спрашивать что непонятно.

Сейчас нужно сделать приборчик-контроллер который:
1. считывал 5 датчиков температуры (каждый датчик на своем пине)
2. выводил все это на экран
3. возможность поддержания on/off заданного одного из двух температурных режимов
4. переключение режимов
5. выведение записей на POS принтер
* возможно архивация данных на СД карте
DSCN0976.jpg (12413 просмотров) <a class='original' href='./download/file.php?id=9074&sid=d683ab6ea85ce4762889afb7be06fdd6&mode=view' target=_blank>Загрузить оригинал (227.92 КБ)</a>
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

как урезать один знак после запятой?

В переменную temp1 записывается температура
float temp1;

и она выводится как 25,32 а мне нужно чтоб 25,3 (лишний знак срезать или округлить)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Аватара пользователя
Тима
Почётный участник
Почётный участник
Сообщения: 3162
Зарегистрирован: 01 мар 2012, 20:47
Репутация: 1089
Настоящее имя: Тимур
Откуда: КБР
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Тима »

aftaev писал(а):как урезать один знак после запятой?
Синтаксис

Serial.print(val)
Serial.print(val, format)

Параметры

val: данные для передачи через последовательное соединение
format: базис для целых чисел или количество знаков после запятой для вещественных
Дорогу осилит идущий!
Я все пойму, Вы только дайте денег!!!
Аватара пользователя
Тима
Почётный участник
Почётный участник
Сообщения: 3162
Зарегистрирован: 01 мар 2012, 20:47
Репутация: 1089
Настоящее имя: Тимур
Откуда: КБР
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Тима »

Вот здесь вычитал: http://arduino.ru/Reference/Serial/Print
Дорогу осилит идущий!
Я все пойму, Вы только дайте денег!!!
Аватара пользователя
Rafiq
Мастер
Сообщения: 1053
Зарегистрирован: 28 сен 2012, 18:11
Репутация: 6
Откуда: Tatarstan Respublikası, Yar Çallı şəhəre
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Rafiq »

Если на дисплейчик, то сначала преобразуй в строку:

Код: Выделить всё

...
char buffer[5];
...
sprintf(buffer, "%f5.1", temp1);
...
а потом выводи buffer на дисплей.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Nick »

А лучше сразу всю строку через sprintf, как я тебе и говорил! :)
Аватара пользователя
Rafiq
Мастер
Сообщения: 1053
Зарегистрирован: 28 сен 2012, 18:11
Репутация: 6
Откуда: Tatarstan Respublikası, Yar Çallı şəhəre
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Rafiq »

Если число - часть большей строки, то несомненно.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

Тима писал(а):Вот здесь вычитал: http://arduino.ru/Reference/Serial/Print
lcd.println(temp1,1);
выводит 24.9##
## - это непонятные аброкадабры.
Тима, твой пример проиграл. Буду разбираться то что Nick написал :)
Nick писал(а):А лучше сразу всю строку через sprintf, как я тебе и говорил!
Дык там столько букФ непонятных что без :beer_blow: не переваривается :)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

Nick писал(а):А лучше сразу всю строку через sprintf, как я тебе и говорил!
пробовал sprintf и без s printf выдает ошибку

Код: Выделить всё

#include <LiquidCrystal.h> /* Подключаем библиотеку для работы с LCD */

//режимы
int Fr_min=23.33; // переменная ферментация мин.
int Fr_max=23.33; // переменная ферментация макс.
int Ps_min=23.33; // переменная пастеризация мин.
int Ps_max=23.33; // переменная пастеризация макс.
char myChar ;
int Pos_min=30; // переменная выдача данных на принтер

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//static FILE lcdout = {0} ;      // LCD FILE structure

void setup() // настраиваем
{
   lcd.begin(16, 2);  /* Инициализируем дисплей: 2 строки по 16 символов */

   lcd.setCursor(5, 1);  //позиция курсора (столбец, строка)
   lcd.print("DS18B20 "); // выводим приветсвие
   delay(5000); // пауза 3 сек
   lcd.clear(); // очищаем
}   

//--------------------------------------------------------------------------------------------------------------------------------------------------
//                                            ОСНОВНАЯ ПРОГРАММА
//--------------------------------------------------------------------------------------------------------------------------------------------------
void loop(void)  // основной цикл
{ 

printf(myChar,"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);
lcd.print(myChar);

}  
выдает ошибку:
printf.cpp: In function 'void loop()':
printf:33: error: invalid conversion from 'char' to 'const char*'
printf:33: error: initializing argument 1 of 'int printf(const char*, ...)'
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

Тима, Nick, ваш код проиграл :)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Nick »

aftaev писал(а):printf(myChar,"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);
тут нужен sprintf, а не printf, т.к. первый аргумент это строка, куда хочешь сохранить результат.
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5181
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Serg »

Rafiq писал(а):Если число - часть большей строки, то несомненно.
В большом компе так конечно удобнее, а вот в маленьком МК так потратится больше дефицитной оперативной памяти на буфер для всей строки (для результата sprintf).
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

Nick писал(а):тут нужен sprintf, а не printf, т.к. первый аргумент это строка, куда хочешь сохранить результат.

Код: Выделить всё

[b]char s ;[/b]

//--------------------------------------------------------------------------------------------------------------------------------------------------
//                                            ОСНОВНАЯ ПРОГРАММА
//--------------------------------------------------------------------------------------------------------------------------------------------------
void loop(void)  // основной цикл
{ 
[b]s[/b]printf([b]s[/b],"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);
lcd.print([b]s[/b]);
}  
результат:
printf.cpp: In function 'void loop()':
printf:33: error: invalid conversion from 'char' to 'char*'
printf:33: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)'
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

UAVpilot, как нужно? Только в виде кода :)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5181
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Serg »

char s[5];
...
lcd.print("Размер программы ");
sprintf(s, "%i", strcount);
lcd.print(s);
lcd.print(" строк кода.");

В этом случае в RAM задействуется только 5 байт, а все слова будут выводится прямо из flash для программы (сегмент кода).
А если делать одной строкой, то сначала sprintf скопирует слова из flash в RAM, где соотв. потребуется организовать буфер нужного размера, а уже оттуда на экран.
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
wldev
Мастер
Сообщения: 1639
Зарегистрирован: 24 янв 2012, 16:04
Репутация: 510
Настоящее имя: Сергей Бочаров
Откуда: Новосибирск
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение wldev »

aftaev писал(а):как урезать один знак после запятой?
вот тебе табуляция
tab(123.416,0) //124
tab(123.416,1) //123.4
tab(123.416,2) //124.42

Код: Выделить всё

float tab(float data,int n)
{
float ret;
long  buf;
long  k=1;

while(n--)  k*=10;

buf=data*=k;

if((data-buf)>0.5) buf++;

ret=buf;

return  ret/k;
}
а если просто обрезать один знак то

Код: Выделить всё

float temp=36.67;
long buf;

buf=temp*10; //366
temp=buf;    //366.0
temp=/10;   //36.6
Новости: https://t.me/wldevruch
Обсуждения: https://t.me/wldevgr
Аватара пользователя
Rafiq
Мастер
Сообщения: 1053
Зарегистрирован: 28 сен 2012, 18:11
Репутация: 6
Откуда: Tatarstan Respublikası, Yar Çallı şəhəre
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Rafiq »

aftaev писал(а):
Nick писал(а):тут нужен sprintf, а не printf, т.к. первый аргумент это строка, куда хочешь сохранить результат.

Код: Выделить всё

[b]char s ;[/b]

//--------------------------------------------------------------------------------------------------------------------------------------------------
//                                            ОСНОВНАЯ ПРОГРАММА
//--------------------------------------------------------------------------------------------------------------------------------------------------
void loop(void)  // основной цикл
{ 
[b]s[/b]printf([b]s[/b],"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);
lcd.print([b]s[/b]);
}  
результат:
printf.cpp: In function 'void loop()':
printf:33: error: invalid conversion from 'char' to 'char*'
printf:33: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)'
Ну естeственно. первый аргумент sprintf - должен быть указателем на буфер, а s объявлена как просто char.
Объявление должно быть таким:

Код: Выделить всё

char s[BUFFER_SIZE]; // вместо BUFFER_SIZE подставить конкретную константу, а лучше объявить через #define
Та же ошибка и в посте #9 - myChar должен быть объявлен как массив.
Последний раз редактировалось Rafiq 07 ноя 2012, 08:26, всего редактировалось 1 раз.
Аватара пользователя
Rafiq
Мастер
Сообщения: 1053
Зарегистрирован: 28 сен 2012, 18:11
Репутация: 6
Откуда: Tatarstan Respublikası, Yar Çallı şəhəre
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение Rafiq »

UAVpilot писал(а):char s[5];
...
lcd.print("Размер программы ");
sprintf(s, "%i", strcount);
lcd.print(s);
lcd.print(" строк кода.");

В этом случае в RAM задействуется только 5 байт, а все слова будут выводится прямо из flash для программы (сегмент кода).
А если делать одной строкой, то сначала sprintf скопирует слова из flash в RAM, где соотв. потребуется организовать буфер нужного размера, а уже оттуда на экран.
Да, для МК вообще говоря лучше так. Но я стараюсь писать программы проще, а оптимизировать только если не хватает ресурсов. И для дисплея выделить буфер всего в 32 байта мне кажется проблемы не составит. Кроме того, на таких дисплеях поясняющие надписи (постоянная часть строки) обычно имеют длину сравнимую или даже меньшую чем длина значения отображаемых величин.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

Исправил на массив char s[5];
Ошибки нет, но и экран пустой :thinking:

Код
(для просмотра содержимого нажмите на ссылку)

Код: Выделить всё

#include <LiquidCrystal.h> /* Подключаем библиотеку для работы с LCD */

//режимы
int Fr_min=23.33; // переменная ферментация мин.
int Fr_max=23.33; // переменная ферментация макс.
int Ps_min=23.33; // переменная пастеризация мин.
int Ps_max=23.33; // переменная пастеризация макс.
char s[5];
int Pos_min=30; // переменная выдача данных на принтер

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//static FILE lcdout = {0} ;      // LCD FILE structure

void setup()
{
   lcd.begin(16, 2);  /* Инициализируем дисплей: 2 строки по 16 символов */

   lcd.setCursor(5, 1);  //позиция курсора (столбец, строка)
   lcd.print("DS18B20 "); // выводим приветсвие
   delay(5000); // пауза 3 сек
   lcd.clear(); // очищаем
}   

//--------------------------------------------------------------------------------------------------------------------------------------------------
//                                            ОСНОВНАЯ ПРОГРАММА
//--------------------------------------------------------------------------------------------------------------------------------------------------
void loop(void)  // основной цикл
{ 
sprintf(s,"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);
lcd.print(s);
}
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
Сообщения: 34042
Зарегистрирован: 04 апр 2010, 19:22
Репутация: 6192
Откуда: Казахстан.
Контактная информация:

Re: Мои проекты на Ардуино

Сообщение aftaev »

Bender писал(а):вот тебе табуляция
tab(123.416,0) //124
tab(123.416,1) //123.4
tab(123.416,2) //124.42
Если передаю переменную, сколько бы не ставил после запятой знаков выводит так 23.00 Мне один ноль лишний и нужно 23,3.
(для просмотра содержимого нажмите на ссылку)
// описание языка http://arduino.ru/Reference

#include <LiquidCrystal.h> /* Подключаем библиотеку для работы с LCD */

//режимы
int Fr_min=23.33; // переменная ферментация мин.
int Fr_max=23.33; // переменная ферментация макс.
int Ps_min=23.33; // переменная пастеризация мин.
int Ps_max=23.33; // переменная пастеризация макс.
char s[5];
int Pos_min=30; // переменная выдача данных на принтер

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//static FILE lcdout = {0} ; // LCD FILE structure

void setup()
{
lcd.begin(16, 2); /* Инициализируем дисплей: 2 строки по 16 символов */

lcd.setCursor(5, 1); //позиция курсора (столбец, строка)
lcd.print("DS18B20 "); // выводим приветсвие
delay(5000); // пауза 3 сек
lcd.clear(); // очищаем
}

//--------------------------------------------------------------------------------------------------------------------------------------------------
// ОСНОВНАЯ ПРОГРАММА
//--------------------------------------------------------------------------------------------------------------------------------------------------
void loop(void) // основной цикл
{
lcd.clear(); // очищаем
//sprintf(s,"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);
//lcd.print(s);

lcd.print(tab(Fr_min,1)); //124
delay(5000); // пауза 3 сек
}

//*************************************************************************************************************************************************
float tab(float data,int n)
{
float ret;
long buf;
long k=1;

while(n--) k*=10;

buf=data*=k;

if((data-buf)>0.5) buf++;

ret=buf;

return ret/k;
}
Если пишу число так
lcd.print(tab(23.55,1)); //124
то выводит 23,50 Ноль опять лишний
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Ответить

Вернуться в «Электроника»