Страница 1 из 14

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

Добавлено: 06 ноя 2012, 21:39
aftaev
Буду выкладывать то что сделал на Ардуино. Изучаю Си и привыкаю к синтаксису языка.
Потому буду спрашивать что непонятно.

Сейчас нужно сделать приборчик-контроллер который:
1. считывал 5 датчиков температуры (каждый датчик на своем пине)
2. выводил все это на экран
3. возможность поддержания on/off заданного одного из двух температурных режимов
4. переключение режимов
5. выведение записей на POS принтер
* возможно архивация данных на СД карте
DSCN0976.jpg (12735 просмотров) <a class='original' href='./download/file.php?id=9074&mode=view' target=_blank>Загрузить оригинал (227.92 КБ)</a>

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
Тима
Вот здесь вычитал: http://arduino.ru/Reference/Serial/Print

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
Тима писал(а):Вот здесь вычитал: http://arduino.ru/Reference/Serial/Print
lcd.println(temp1,1);
выводит 24.9##
## - это непонятные аброкадабры.
Тима, твой пример проиграл. Буду разбираться то что Nick написал :)
Nick писал(а):А лучше сразу всю строку через sprintf, как я тебе и говорил!
Дык там столько букФ непонятных что без :beer_blow: не переваривается :)

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];
Ошибки нет, но и экран пустой :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);
}

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 Ноль опять лишний