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

Контроллеры, драйверы, датчики, управляющие устройства.

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

Сообщение aftaev » 06 ноя 2012, 21:39

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

Сейчас нужно сделать приборчик-контроллер который:
1. считывал 5 датчиков температуры (каждый датчик на своем пине)
2. выводил все это на экран
3. возможность поддержания on/off заданного одного из двух температурных режимов
4. переключение режимов
5. выведение записей на POS принтер
* возможно архивация данных на СД карте

Мои проекты на Ардуино DSCN0976.jpg
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение aftaev » 06 ноя 2012, 21:41

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

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

и она выводится как 25,32 а мне нужно чтоб 25,3 (лишний знак срезать или округлить)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение Тима » 06 ноя 2012, 22:00

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


Синтаксис

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

Параметры

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

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

Сообщение Тима » 06 ноя 2012, 22:02

Вот здесь вычитал: http://arduino.ru/Reference/Serial/Print
Дорогу осилит идущий!
Я все пойму, Вы только дайте денег!!!
Аватара пользователя
Тима
Почётный участник
Почётный участник
 
Сообщения: 3138
Зарегистрирован: 01 мар 2012, 20:47
Откуда: КБР
Репутация: 1084
Медальки:
Настоящее имя: Тимур

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

Сообщение Rafiq » 06 ноя 2012, 22:10

Если на дисплейчик, то сначала преобразуй в строку:
Код: Выделить всёРазвернуть
...
char buffer[5];
...
sprintf(buffer, "%f5.1", temp1);
...

а потом выводи buffer на дисплей.
Аватара пользователя
Rafiq
Мастер
 
Сообщения: 1053
Зарегистрирован: 28 сен 2012, 18:11
Откуда: Tatarstan Respublikası, Yar Çallı şəhəre
Репутация: 6
Медальки:

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

Сообщение Nick » 06 ноя 2012, 22:16

А лучше сразу всю строку через sprintf, как я тебе и говорил! :)
Аватара пользователя
Nick
Мастер
 
Сообщения: 22552
Зарегистрирован: 23 ноя 2009, 16:45
Откуда: Gatchina, Saint-Petersburg distr., Russia
Репутация: 1571
Заслуга: Developer
Медальки:

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

Сообщение Rafiq » 06 ноя 2012, 22:54

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

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

Сообщение aftaev » 06 ноя 2012, 23:40

Тима писал(а):Вот здесь вычитал: http://arduino.ru/Reference/Serial/Print

lcd.println(temp1,1);
выводит 24.9##
## - это непонятные аброкадабры.
Тима, твой пример проиграл. Буду разбираться то что Nick написал :)

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

Дык там столько букФ непонятных что без :beer_blow: не переваривается :)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение aftaev » 07 ноя 2012, 00:11

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
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение aftaev » 07 ноя 2012, 00:12

Тима, Nick, ваш код проиграл :)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение Nick » 07 ноя 2012, 00:30

aftaev писал(а):printf(myChar,"Fr%d-%d Ps%d-%d\nPrint %d min", Fr_min,Fr_max,Ps_min,Ps_max,Pos_min);

тут нужен sprintf, а не printf, т.к. первый аргумент это строка, куда хочешь сохранить результат.
Аватара пользователя
Nick
Мастер
 
Сообщения: 22552
Зарегистрирован: 23 ноя 2009, 16:45
Откуда: Gatchina, Saint-Petersburg distr., Russia
Репутация: 1571
Заслуга: Developer
Медальки:

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

Сообщение UAVpilot » 07 ноя 2012, 00:45

Rafiq писал(а):Если число - часть большей строки, то несомненно.

В большом компе так конечно удобнее, а вот в маленьком МК так потратится больше дефицитной оперативной памяти на буфер для всей строки (для результата sprintf).
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
UAVpilot
Мастер
 
Сообщения: 18514
Зарегистрирован: 17 апр 2012, 14:58
Откуда: Москва
Репутация: 4535
Медальки:
Настоящее имя: Сергей

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

Сообщение aftaev » 07 ноя 2012, 01:10

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
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение aftaev » 07 ноя 2012, 01:11

UAVpilot, как нужно? Только в виде кода :)
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение UAVpilot » 07 ноя 2012, 01:42

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

В этом случае в RAM задействуется только 5 байт, а все слова будут выводится прямо из flash для программы (сегмент кода).
А если делать одной строкой, то сначала sprintf скопирует слова из flash в RAM, где соотв. потребуется организовать буфер нужного размера, а уже оттуда на экран.
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
UAVpilot
Мастер
 
Сообщения: 18514
Зарегистрирован: 17 апр 2012, 14:58
Откуда: Москва
Репутация: 4535
Медальки:
Настоящее имя: Сергей

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

Сообщение Bender » 07 ноя 2012, 05:09

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
WL - We Love )))
Аватара пользователя
Bender
Мастер
 
Сообщения: 773
Зарегистрирован: 24 янв 2012, 16:04
Откуда: Новосибирск
Репутация: 209
Медальки:
Настоящее имя: Сергей Бочаров

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

Сообщение Rafiq » 07 ноя 2012, 08:12

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
Откуда: Tatarstan Respublikası, Yar Çallı şəhəre
Репутация: 6
Медальки:

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

Сообщение Rafiq » 07 ноя 2012, 08:17

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

В этом случае в RAM задействуется только 5 байт, а все слова будут выводится прямо из flash для программы (сегмент кода).
А если делать одной строкой, то сначала sprintf скопирует слова из flash в RAM, где соотв. потребуется организовать буфер нужного размера, а уже оттуда на экран.

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

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

Сообщение aftaev » 07 ноя 2012, 08:59

Исправил на массив 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
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

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

Сообщение aftaev » 07 ноя 2012, 09:06

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 Ноль опять лишний
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
aftaev
Зачётный участник
Зачётный участник
 
Сообщения: 30544
Зарегистрирован: 04 апр 2010, 19:22
Откуда: Казахстан. Шымкент
Репутация: 5424
Медальки:

След.

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

Кто сейчас на конференции

Зарегистрированные пользователи: Adskiydart, Alexf2a, Bender, Bing [Bot], Enot_1, error101, gennadiy, Google [Bot], ignatov-alex, iMaks-RS, Kachik, MGG, Nikitay, pegas13, Power968, sivolap36, stanislavpetrashko, Tillman, UAVpilot, Yandex [bot], Иван Карел, шпиндель

Reputation System ©'