Как строку с сериал преобразовать в uint64_t

ingfa
Offline
Зарегистрирован: 15.09.2018

Пробовал разобраться сам не смог осилить, как строку  полученную с сериал порта преобразовать в uint64_t?

Попалась такая информация по scanf.

Правильный формат для чтения uint64_t (typedef unsigned long long int) - это scanf , а не sscanf"%" SCNu64 , а для печати также пример SCNu64 . в своем коде вы читаете, например, переменную my_integer, а затем делаете scanf ("Value of integer:%" SCNu64, & my_integer); и написать то же самое, но с printf.

Можно конкретный пример с этой строкой или другие какие методы есть число 10200000000ULL получить из строки?

scanf ("Value of integer:%" SCNu64, & my_integer);

rkit
Offline
Зарегистрирован: 23.11.2016

Читай документацию, а не какие-то левые обсуждения вещей которых ты не понимаешь.

b707
Offline
Зарегистрирован: 26.05.2017

ingfa пишет:

Пробовал разобраться сам не смог осилить, как строку  полученную с сериал порта преобразовать в uint64_t?

ну например прочитай из Сериал два числа uint32 и потом умножь их друг на друга...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ingfa,

я как-то запускал эти форматы для scanf/printf, они не заработали (правда, я особо не напрягался разбираться что именно пошло не так).

А что Вам мешает просто вручную преобразовать 64-битное беззнаковое в строку и обратно? По мне так, даже если это писать тупо в лоб, безо всякой оптимизации, всё равно должно быть лучше scanf/printf по времени, а про память я уж вообще молчу.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Это ж ввод-вывод. Оптимизация не имеет смысла.

Вот, пусть будет ради "отмывки кармы" ;))

char * u64itoa(uint64_t u) {
  static char ret[32];
  ret[31] = 0;

  byte i;
  for (i = 30; i >= 0 and u != 0; u /= 10) ret[--i] = (u % 10) + '0';
  return (char *)(ret + i);
}

uint64_t u64atoi(char * s) {
  uint64_t r;
  for (r = 0; *s; r = r * 10 + *(s++) - '0');
  return r;
}

void setup() {
  Serial.begin(115200);

  const char * sss[4] = {"2222222222222", "333333333333333", "44444444444444444", "5555555555555555555"};
  uint64_t iii[4];
  byte i = 0;
  
  for (auto s:sss) iii [i++] = u64atoi(s);
  
  for (auto i : iii)
    Serial.println( u64itoa(i / 11));

}

void loop() {
  // put your main code here, to run repeatedly:

}

От опять забыл дописать.

Проверено на Нано old bootloader, IDE 1.8.13

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Оно, конечно,

wdrakula пишет:
Оптимизация не имеет смысла.

но, всё-таки

wdrakula пишет:

  static char ret[32]; 

21 - за глаза хватит.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ЕвгенийП пишет:

Оно, конечно,

wdrakula пишет:
Оптимизация не имеет смысла.

но, всё-таки

wdrakula пишет:

  static char ret[32]; 

21 - за глаза хватит.

мы фкурсе! ;)) но 32 - это степень двойки... сам понимаешь, хотя 21 - тоже знатное число!

(Ох не очко меня сгубило, а к одиннадцати туз!)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так и я ж подумал, что использовать большее значение, чем 21 - перебор! :-)

ingfa
Offline
Зарегистрирован: 15.09.2018

ЕвгенийП пишет:

Так и я ж подумал, что использовать большее значение, чем 21 - перебор! :-)

Спасибо вам ЕвгенийП, когда то давно вы написали такой код

template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }

enum AUTOMATA_STATE { // Возможные состояния разборщика
	WAITING_AMPERSAND,	// ожидание начала пакета
	WAITING_NAME, 	//	ожидание имени
	WAITING_NUMBER	//	ожидание числа
};

#define	PACKET_BEGIN	'&'

void setup(void) {
	Serial.begin(115200);
}

void loop(void) {
	// Изначально автомат в состоянии ожидания
	static AUTOMATA_STATE state = WAITING_AMPERSAND;
	static char variableName;
	
	if (! Serial.available()) return;	// не пришёл символ? Ну, и нечего тут делать
	//
	// Что делать дальше определяется состоянием автомата
	switch (state) {
		case WAITING_AMPERSAND:
			// В состоянии ожидания мы ждём символа PACKET_BEGIN и игнорируем любые другие
			if (Serial.read() != PACKET_BEGIN) return;
			// Пришёл символ начала пакета. Переходим в состояние PARSING
			state = WAITING_NAME;
			break;
		case WAITING_NAME:
			// В состоянии ожидания имени мы мы должны получить латинскую букву. 
			// Если получили - переходим в состояние ввода числа
			// Если пришло что-то другое - ошибка, переходим обратно в ожидание &
			variableName = Serial.read();
			state = isalpha(variableName) ? WAITING_NUMBER : WAITING_AMPERSAND;
			break;
		case WAITING_NUMBER:
			// читаем число
			float value;
			Serial.readBytes((byte *) & value, sizeof(value));
			///////////////////////////
			//	В этом месте мы имеем результат !!!!
			//	Имя находится в переменной variableName, а значение - в переменной value
			//	Что с ними делать решайте сам - сериал-то у нас занят другим устройством
			//	так что печатать результат некуда
			///////////////////////////
			state = WAITING_AMPERSAND;
			break;
	}
}

Я его переделал float value на uint64_t.

А через python 3 я передаю переменную, 

peremennya = 10200000000 согласно https://docs.python.org/3/library/struct.html

peremennya = struct.pack( "Q",peremennya 

serial.write(peremennya)