Помогите преобразовать тип
- Войдите на сайт для отправки комментариев
Пт, 14/12/2012 - 23:25
Здравствуйте!
помогите пожалуйста кусочком кода...
Есть переменная integer. Принимает значение от 0 до 20.
нужно ее значение записать в char[2]
пример: i=14 то с[0]="1" и с[1]="4"
Спасибо за помощь!
Я бы сделал так:
Оба варианта имеют место жить :)
В первом варианте только нужно объявить буфер достаточной длины, не меньше 3-х.
Есть еще один вариант, itoa.
А вообще, если нужен корректный ответ - нужен корректный вопрос ;) Я про то, как далее будет использоваться строковое значение. Например, если просто вывести в Serial, тогда и преобразование не нужно.
а я бы сделал так :
Я не знал про itoa... спасибо.
PS. А мысль с делением сразу пришла, но как-то читал статью, в которой программист старательно избегал разными путями деления, пояснив, что это очень ресурсоемкое мероприятие...
sprintf - наиболее универсальный вариант, но и более ресурсоемкий, потому что универсальный. Вариант максима самый эффективный, если не рассматривать дальнейшее использование строки. Хотя справедливости ради нужно добавить код '0', чтобы это были символы (chislo/10 + '0' и chislo%10 + '0'). Ну и вариант с itoa - середина :)
Деление, по большому счету, лучше избегать - если деление не на степень двойки (1,2,4,8,16,32..). Например, деление на 4, можно заменить на сдвиг вправо на 2. Хотя всё это философия, нужно смотреть для чего это нужно и нужно ли это.
А вы думаете, что внутри itoa не деление, а какая то волшебная операция?
Топик-стартер не пояснил, что ему нужно строка с кодами АСКИ или просто цифры.
А еще можно сделать без умножения и деления, просто и тупо:
char *gp_array[] = { "00", "01", "02", "03", "04" ... "20" }; int value = 5; char *ptr = gp_array[ value ];И массив поместить в PROGMEM.
А вы думаете, что внутри itoa не деление, а какая то волшебная операция?
Не берусь спорить, просто выразил свои опасения (я еще "чайник").
Про функцию itoa нашел тут: http://ru.wikipedia.org/wiki/Itoa_(%D0%A1%D0%B8)
там пример ее реализации...
А пример с памятью - шикарен)
Массив хорош, но в жизни не используется, потому что ограничен объемом памяти и набором входных значений.
А наоборот это тоже работает? К примеру присвоить содержимое char to int.
А наоборот это тоже работает? К примеру присвоить содержимое char to int.
Например функция: atoi
http://ru.wikipedia.org/wiki/Atoi
еще можно вычислять значение АСКИ символа - тоесть значение каждого char в массиве. По ASCII http://www.asciitable.com/ таблице - где они идут по порядку, нужно отнять абсолютное значение аски (тоесть значение нуля по таблице - это 48) и получится число, дальше прибавлять его к итоговому int домножая на разрядность.
Например: 52 - берем первый с начала знак 5 - в аски это значение 53 (а 0 это 48) - значит вычитаем из 53 - 48 = 5
умнажаем 5 * 10 и прибавляем в нужный int. получилось в int=50
затем берем 2, в аски это 50, отнимаем 48 (тоесть 0) = 2 *1 + к тому же int = 52
оформляем цикл - получаем автоматическое преобразование - только нужно знать количество знаков в char, чтобы задать размерность цикла и не переборщить с размерностью int.
PS. Выше ИМХО - просьба не пинать)
Как то так?
Спасибо большое!!!!
Как то так?
Вроде и компелятор не ругается, а программа всё равно не работает.
Вот часть кода. Цель, с помощью таймера изменять частоту мигания леда. Величину таймера я посылаю с терминала.
К примеру 013,on,500
013 - Устройство. on - команда "Включить". 500 - 500mS
Что-же я упускаю?
#include <string.h> char unitID_in[10]; char command_in[10]; char data_in[100]; int interval_1; unsigned long newMillis_1; void setup() { // открываем порт Serial.begin(9600); // к пину 8 подключён led pinMode(8, OUTPUT); } void loop() { int i=0; char buffer[100]; //если есть данные - читаем if(Serial.available()) { delay(100); //загоняем прочитанное в буфер while( Serial.available() && i< 99) { buffer[i++] = Serial.read(); } //закрываем массив buffer[i++]='\0'; } //если буфер наполнен if(i>0) { //разбераем его на части отделенные запятой sscanf(buffer, "%[^','],%[^','],%s", &unitID_in, &command_in, &data_in); } //Исполнительная часть //Проверяем какому устройству пришли данные //тестовое устройство 001 if ((String)unitID_in == "001") { //test serial read interval_1 = atoi(data_in); Serial.print("001,arduino recive: unit "); Serial.print(unitID_in); Serial.print("\n"); Serial.print("command: "); Serial.print(command_in); Serial.print("\n"); Serial.print("data: "); Serial.print(data_in); Serial.print("\n"); Serial.print("interval_1: "); Serial.print(interval_1,DEC); Serial.print("\n"); unitID_in [0] = '\0'; command_in [0] = '\0'; } //пример выполнения команды устройством 013 if ((String)unitID_in == "013") { if ((String)command_in == "on") { interval_1 = atoi(data_in); if(millis() > newMillis_1) { digitalWrite(8, !digitalRead(8)); newMillis_1 = millis() + interval_1; } } if ((String)command_in == "off") { digitalWrite(8, LOW); } Serial.print("001,arduino recive: unit "); Serial.print(unitID_in); Serial.print(" command "); Serial.print(command_in); Serial.print("\n"); Serial.print("interval_1: "); Serial.print(interval_1,DEC); Serial.print("\n"); unitID_in [0] = '\0'; command_in [0] = '\0'; } }32 строку перенесите и вставьте после 36, иначе в каждом loop, происходит "чудо", если нет данных, buffer очищается И увеличивается i, что явно нежелательно
Рекомендую статью по преобразованию целого в строку
Есть, разобрался!
Теперь работает!
#include <string.h> char unitID_in[10]; char command_in[10]; char data_in[100]; int interval_1; unsigned long newMillis_1; void setup() { // открываем порт Serial.begin(9600); pinMode(8, OUTPUT); } void loop() { int i=0; char buffer[100]; //если есть данные - читаем if(Serial.available()) { delay(100); //загоняем прочитанное в буфер while( Serial.available() && i< 99) { buffer[i++] = Serial.read(); } //закрываем массив //buffer[i++]='\0'; } //если буфер наполнен if(i>0) { buffer[i++]='\0'; //разбераем его на части отделенные запятой sscanf(buffer, "%[^','],%[^','],%s", &unitID_in, &command_in, &data_in); } //Исполнительная часть //Проверяем какому устройству пришли данные //тестовое устройство 001 if ((String)unitID_in == "001") { //test serial read interval_1 = atoi(data_in); Serial.print("001,arduino recive: unit "); Serial.print(unitID_in); Serial.print("\n"); Serial.print("command: "); Serial.print(command_in); Serial.print("\n"); Serial.print("data: "); Serial.print(data_in); Serial.print("\n"); Serial.print("interval_1: "); Serial.print(interval_1,DEC); Serial.print("\n"); unitID_in [0] = '\0'; command_in [0] = '\0'; } //пример выполнения команды устройством 013 if ((String)unitID_in == "013") { if ((String)command_in == "on") { interval_1 = atoi(data_in); } if ((String)command_in == "off") { digitalWrite(8, LOW); } Serial.print("001,arduino recive: unit "); Serial.print(unitID_in); Serial.print(" command "); Serial.print(command_in); Serial.print("\n"); Serial.print("interval_1: "); Serial.print(interval_1,DEC); Serial.print("\n"); unitID_in [0] = '\0'; command_in [0] = '\0'; } // Мигание ледом if(millis() > newMillis_1) { digitalWrite(8, !digitalRead(8)); newMillis_1 = millis() + interval_1; } }Подскажите, хочу записать в файл строку состоящую из температуры с датчика и времени. И что-то не получается вывести значение температуры. Перевожу из float в char. В порту отображается строка:
а код вот такой:
File myFile; OneWire ds(8); // линия 1-Wire будет на pin 8 int led = 9; int sec; int minut; int hours; int days; int months; int years; char filename[30]; char date[8]; void setup(void) { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); // On the Ethernet Shield, CS is pin 4. It's set as an output by default. // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. sec = RTC.get(DS1307_SEC, true); //set the seconds minut = RTC.get(DS1307_MIN, true); //set the minutes hours = RTC.get(DS1307_HR, true); //set the hours days = RTC.get(DS1307_DATE, true); //set the date months = RTC.get(DS1307_MTH, true); //set the month years = RTC.get(DS1307_YR, true); //set the year sprintf(filename, "%02d_%02d.txt", days, months); } void loop(void) { digitalWrite(led, HIGH); delay (1000); byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; } ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } // convert the data to actual temperature unsigned int raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // count remain gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms // default is 12 bit resolution, 750 ms conversion time } sec = RTC.get(DS1307_SEC, true); //set the seconds minut = RTC.get(DS1307_MIN, true); //set the minutes hours = RTC.get(DS1307_HR, true); //set the hours days = RTC.get(DS1307_DATE, true); //set the date months = RTC.get(DS1307_MTH, true); //set the month years = RTC.get(DS1307_YR, true); //set the year celsius = (float)raw / 16.0; sprintf(date, "%5.2f_%02d", celsius, months); myFile = SD.open(filename, FILE_WRITE); if (myFile) { myFile.println(date); // close the file: Serial.println(date); myFile.close(); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } delay (100); }Подскажите, хочу записать в файл строку состоящую из температуры с датчика и времени. И что-то не получается вывести значение температуры. Перевожу из float в char. В порту отображается строка:
Наталкивался на то что то-ли sprintf, то ли scanf, то ли оба (не помню точно, лень выкапывать) - на ардуине, для экономии памяти реализованы не в полном объеме. представляют собой "обкусанный вариант" который не умеет работать с float. Реализована поддержка только целых и строк.
Так, что, с большой доле вероятности вам нужно будет либо предварительно разбирать celsius на целую и дробную часть и кормить их sprintf-у отдельно. Либо самому делать преобразование float в строку.
Можно так сделать:
celsius = (float)raw / 16.0; myFile = SD.open(filename, FILE_WRITE); if (myFile) { myFile.print(celsius, 2); myFile.print('_'); if(months < 10)myFile.print('0'); myFile.println(months); Serial.print(celsius, 2); Serial.print('_'); if(months < 10)Serial.print('0'); Serial.println(months); myFile.close(); } else Serial.println("error opening test.txt"); delay (100);только вот не понятно зачем вы только месяц записываете?
Можно так сделать:
celsius = (float)raw / 16.0; myFile = SD.open(filename, FILE_WRITE); if (myFile) { myFile.print(celsius, 2); myFile.print('_'); if(months < 10)myFile.print('0'); myFile.println(months); Serial.print(celsius, 2); Serial.print('_'); if(months < 10)Serial.print('0'); Serial.println(months); myFile.close(); } else Serial.println("error opening test.txt"); delay (100);только вот не понятно зачем вы только месяц записываете?
благодарю! да это я для теста, чтобы всю строку не писать. А сейчас всё прописал. Еще вот такой вопрос, записываю в имя создаваемого файла значения даты, но больше двух типов(например, месяца и года или дня и месяца) не получается записать, не выводится на монитор порта.
Это почему же? Вот все выводится:
Это почему же? Вот все выводится:
выводиться то выводится, а вот почему-то записывать в файл с таким именем данные он не хочет. Наверное больше 8 символов, как где-то писалось.
void setup(void) { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); // On the Ethernet Shield, CS is pin 4. It's set as an output by default. // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(10, OUTPUT); if (!SD.begin(10)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. sec = RTC.get(DS1307_SEC, true); //set the seconds minut = RTC.get(DS1307_MIN, true); //set the minutes hours = RTC.get(DS1307_HR, true); //set the hours days = RTC.get(DS1307_DATE, true); //set the date months = RTC.get(DS1307_MTH, true); //set the month years = RTC.get(DS1307_YR, true); //set the year sprintf(filename, "%02d_%02d_%d.txt", days, months, years); Serial.println(filename); } void loop(void) { digitalWrite(led, HIGH); delay (1000); byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; } ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } // convert the data to actual temperature unsigned int raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // count remain gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms // default is 12 bit resolution, 750 ms conversion time } sec = RTC.get(DS1307_SEC, true); //set the seconds minut = RTC.get(DS1307_MIN, true); //set the minutes hours = RTC.get(DS1307_HR, true); //set the hours days = RTC.get(DS1307_DATE, true); //set the date months = RTC.get(DS1307_MTH, true); //set the month years = RTC.get(DS1307_YR, true); //set the year celsius = (float)raw / 16.0; myFile = SD.open(filename, FILE_WRITE); if (myFile) { myFile.print(celsius, 2); myFile.print('_'); myFile.print(years); myFile.print('-'); myFile.print(months); myFile.print('-'); myFile.print(days); myFile.print(' '); myFile.print(hours); myFile.print(':'); myFile.print(minut); myFile.print(':'); myFile.println(sec); Serial.print(celsius, 2); Serial.print('_'); Serial.print(years); Serial.print('-'); Serial.print(months); Serial.print('-'); Serial.print(days); Serial.print(' '); Serial.print(hours); Serial.print(':'); Serial.print(minut); Serial.print(':'); Serial.println(sec); myFile.close(); } else Serial.println("error opening test.txt"); delay (100); }выводиться то выводится, а вот почему-то записывать в файл с таким именем данные он не хочет. Наверное больше 8 символов, как где-то писалось.
Не "наверное", а так и есть. "Писалось" в документации Arduino - SD :)
Ну так урежте год и получите 8 символов 17_06_13.txt:
И кстати остальную то строку можно и sprintfом формировать: