Страница 1 из 14
Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 21:39
aftaev
Буду выкладывать то что сделал на Ардуино. Изучаю Си и привыкаю к синтаксису языка.
Потому буду спрашивать что непонятно.
Сейчас нужно сделать приборчик-контроллер который:
1. считывал 5 датчиков температуры (каждый датчик на своем пине)
2. выводил все это на экран
3. возможность поддержания on/off заданного одного из двух температурных режимов
4. переключение режимов
5. выведение записей на POS принтер
* возможно архивация данных на СД карте
Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 21:41
aftaev
как урезать один знак после запятой?
В переменную temp1 записывается температура
float temp1;
и она выводится как 25,32 а мне нужно чтоб 25,3 (лишний знак срезать или округлить)
Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 22:00
Тима
aftaev писал(а):как урезать один знак после запятой?
Синтаксис
Serial.print(val)
Serial.print(val, format)
Параметры
val: данные для передачи через последовательное соединение
format: базис для целых чисел или количество знаков после запятой для вещественных
Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 22:02
Тима
Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 22:10
Rafiq
Если на дисплейчик, то сначала преобразуй в строку:
Код: Выделить всё
...
char buffer[5];
...
sprintf(buffer, "%f5.1", temp1);
...
а потом выводи buffer на дисплей.
Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 22:16
Nick
А лучше сразу всю строку через sprintf, как я тебе и говорил!

Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 22:54
Rafiq
Если число - часть большей строки, то несомненно.
Re: Мои проекты на Ардуино
Добавлено: 06 ноя 2012, 23:40
aftaev
l
cd.println(temp1,1);
выводит 24.9##
## - это непонятные аброкадабры.
Тима, твой пример проиграл. Буду разбираться то что Nick написал
Nick писал(а):А лучше сразу всю строку через sprintf, как я тебе и говорил!
Дык там столько букФ непонятных что без

не переваривается

Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 00:11
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*, ...)'
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 00:12
aftaev
Тима,
Nick, ваш код проиграл

Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 00:30
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, т.к. первый аргумент это строка, куда хочешь сохранить результат.
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 00:45
Serg
Rafiq писал(а):Если число - часть большей строки, то несомненно.
В большом компе так конечно удобнее, а вот в маленьком МК так потратится больше дефицитной оперативной памяти на буфер для всей строки (для результата sprintf).
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 01:10
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*, ...)'
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 01:11
aftaev
UAVpilot, как нужно? Только в виде кода

Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 01:42
Serg
char s[5];
...
lcd.print("Размер программы ");
sprintf(s, "%i", strcount);
lcd.print(s);
lcd.print(" строк кода.");
В этом случае в RAM задействуется только 5 байт, а все слова будут выводится прямо из flash для программы (сегмент кода).
А если делать одной строкой, то сначала sprintf скопирует слова из flash в RAM, где соотв. потребуется организовать буфер нужного размера, а уже оттуда на экран.
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 05:09
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
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 08:12
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 должен быть объявлен как массив.
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 08:17
Rafiq
UAVpilot писал(а):char s[5];
...
lcd.print("Размер программы ");
sprintf(s, "%i", strcount);
lcd.print(s);
lcd.print(" строк кода.");
В этом случае в RAM задействуется только 5 байт, а все слова будут выводится прямо из flash для программы (сегмент кода).
А если делать одной строкой, то сначала sprintf скопирует слова из flash в RAM, где соотв. потребуется организовать буфер нужного размера, а уже оттуда на экран.
Да, для МК вообще говоря лучше так. Но я стараюсь писать программы проще, а оптимизировать только если не хватает ресурсов. И для дисплея выделить буфер всего в 32 байта мне кажется проблемы не составит. Кроме того, на таких дисплеях поясняющие надписи (постоянная часть строки) обычно имеют длину сравнимую или даже меньшую чем длина значения отображаемых величин.
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 08:59
aftaev
Исправил на массив char s[5];
Ошибки нет, но и экран пустой
Код
(для просмотра содержимого нажмите на ссылку)Код: Выделить всё
#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);
}
Re: Мои проекты на Ардуино
Добавлено: 07 ноя 2012, 09:06
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
Ноль опять лишний