Проблемы с преобразованием типов данных.

intervision
Offline
Зарегистрирован: 31.03.2017

Суть поэтапно:

Необходимо считывать числа с Serial.read и передавать их в переменную. Изначально для хранения типы переменных объявлялись как int, соответственно, преобразование делалось через String.toInt()

Позже выяснилось, что значение до ~32 000 маловато, было принято решение объявить тип как unsigned int (все равно отрицательные значения не используются).

Далее, стало ясно, что и этого диапазона не хватает и необходимо хранить числа, хотя бы до 999 999, и тут, получается, спасет только long int.

Но с long как раз и возникла проблема. Честно, гуглил активно и усердно и находил массу решений по запросу "преобразование string в long", но что меня смутило и вызвало негодование, так это то, что все примеры, что я видел - это по сути не преобразование непосредственно string, а работа с массивом, обхявленным как char.

И вот, собственно вопрос:
Есть ли способ просто и без лишних хитростей преобразовать строковые данные, полученные с порта и сохранить их как long int?

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

А можно Ваш нынешний скетч посмотреть?

И, кстати, что Вам мешает воспользоваться программой преобразования для массивов char? String без проблем выдаёт своё содержимое в виде указателя на char. Возьмите s.c_str() и преобразовывайте его хоть в long long

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Чем, по-вашему, является объект String?

intervision
Offline
Зарегистрирован: 31.03.2017

Весь не приведу, там уже более 300 строк

unsigned int coldState = word(EEPROM.read(1), EEPROM.read(2));
unsigned int hotState = word(EEPROM.read(3), EEPROM.read(4));

...

  if (svcCmd == "sc")
  {
    Serial.println("==========");
    Serial.println("New COLD state: ");
    String newSc = Serial.readString();
    delay(3000);
    coldState = newSc.toInt();
    Serial.print("Cold State = ");
    Serial.println(coldState);
  }
  
  if (svcCmd == "sh")
  {
    Serial.println("==========");
    Serial.println("New HOT state: ");
    String newSh = Serial.readString();
    delay(3000);
    hotState = newSh.toInt();
    Serial.print("Hot State = ");
    Serial.println(hotState);
  }

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

Возьмите s.c_str() и преобразовывайте его хоть в long long

А можно про  это поподробнее?

 

Yarik.Yar пишет:

Чем, по-вашему, является объект String?

По-моему, объект String является строкой.

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

Блин, Вы издеваетесь над нами?

У Вас же уже ВСЁ написано!

Вы вообще в курсе. что делает метод toInt и какое значение он возвращает?

Вот его текст

long String::toInt(void) const
{
	if (buffer) return atol(buffer);
	return 0;
}

Он УЖЕ преобразует в long. Просто опишите свой hotState  как long и не пудрите всем мозги!

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

intervision пишет:

А можно про  это поподробнее?

Нельзя! Вы боитесь как бы я не украл Ваш код

intervision пишет:

Весь не приведу

и в результате я должен на хрустальном шаре гадать как у Вас hotState описана. Ну, тогда я тоже боюсь что Вы украдёте мой :)

 

intervision
Offline
Зарегистрирован: 31.03.2017

Спасибо за сдержаный и дружелюбный ответ.

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

Заходите ещё!

intervision
Offline
Зарегистрирован: 31.03.2017

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

Нельзя! Вы боитесь как бы я не украл Ваш код

Было бы чего бояться, если в конечном итоге это все равно планируется в открытый доступ. Решил не выкладывать простыню из вежливости и экономии времени читающего, и оказался виноват...

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

и в результате я должен на хрустальном шаре гадать как у Вас hotState описана. Ну, тогда я тоже боюсь что Вы украдёте мой :)

[/quote]

Хоспади... Вы сегодня не стой ноги встали?

#include <EEPROM.h>
#include <LiquidCrystal.h>

char Version[5] = "0.72";

LiquidCrystal lcd(5, 3, 6, 8, 11, 12);

byte bat100[8] = {
  B01110,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte bat90[8] = {
  B01110,
  B10001,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte bat75[8] = {
  B01110,
  B10001,
  B10001,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte bat50[8] = {
  B01110,
  B10001,
  B10001,
  B10001,
  B11111,
  B11111,
  B11111,
};

byte bat25[8] = {
  B01110,
  B10001,
  B10001,
  B10001,
  B10001,
  B11111,
  B11111,
};

byte bat15[8] = {
  B01110,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11111,
};

byte batLow[8] = {
  B01110,
  B10001,
  B00000,
  B10001,
  B00000,
  B10001,
  B11011,
};

byte CYR_G[8] = {
  B11111,
  B10001,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
};

int batIcon;

int led = 13;
int hot = 7; // Вход со счетчика горячей воды
int cold = 2; // Вход со счетчика холодной воды

unsigned int getCold, getHot, newGetCold, newGetHot;
int timer; // служебное значение системного тайминга
//int coldState, hotState; // Состояние счетчиков
// (нужно сделать энергонезависимым или читать данные из БД)

// the setup routine runs once when you press reset:
void setup() {
  
  analogWrite(A5, 200);
  timer = 0;
  // Обнуленные счетчики для теста и отладки
  // после завершения работы над прибором закомментировать
//  coldState = 0;
//  hotState = 0;
  
  // конец отладки
  
  Serial.begin(9600);
  
  pinMode(led, OUTPUT);
  
  pinMode(cold, INPUT_PULLUP); // Вход для счетчика холодной воды
    attachInterrupt(digitalPinToInterrupt(cold), ColdChange, RISING);
  pinMode(hot, INPUT_PULLUP); // Вход для счетчика горячей воды
  	attachInterrupt(digitalPinToInterrupt(hot), HotChange, RISING);
  
  pinMode(A5, OUTPUT); // Подсветка дисплея
  pinMode(A0, INPUT); // Снятие показаний с источника питания (+5В) для анализа заряда батареи.
  
  // Конфигурация выходов для дисплея (если потребуется)
  pinMode(5, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  // -- //
  
  pinMode(A1, OUTPUT); // Питание светодиода разряда батареи.
  // (При использовании дисплея срабатывает на 4.33 В и ниже)
  // Без дисплея и светодиодов верхний лимит может быть уменьшен.
  
  lcd.createChar(0, bat100);
  lcd.createChar(1, bat90);
  lcd.createChar(2, bat75);
  lcd.createChar(3, bat50);
  lcd.createChar(4, bat25);
  lcd.createChar(5, bat15);
  lcd.createChar(6, batLow);
  
  lcd.createChar(7, CYR_G);
  
  lcd.begin(16, 2);
  lcd.print("WCR v.");
  lcd.print(Version);
  delay(2000);
  lcd.clear();
}

// EEPROM //

unsigned int coldState = word(EEPROM.read(1), EEPROM.read(2));
unsigned int hotState = word(EEPROM.read(3), EEPROM.read(4));

// ------//

void loop() {
// Основное тело кода
  timer++;
  
  while(Serial.available())
  {
   String sread = Serial.readString();
    if (sread == "svc")
    {
      Service();
    }
  }
  
  int bat = analogRead(A0);
  bat = map(bat, 784, 1023, 0, 100);
  Serial.println("============");
  Serial.print("Analog: ");
  Serial.println(analogRead(A0));
  
  Serial.print("Digital: ");
  Serial.println(bat);
  

  if (bat > 90)
  {
    batIcon = 0;
  }
  
  if (bat < 90 and bat >= 80)
  {
    batIcon = 1;
  }
  
  if (bat < 80 and bat >= 70)
  {
      batIcon = 2;
  }
  
  if (bat < 70 and bat >= 50)
  {
    batIcon = 3;
  }
  
  if (bat < 50 and bat >= 40)
  {
	batIcon = 4;
  }
    
  if (bat < 40 and bat >= 20)
  {
    batIcon = 5;
  }
  
  if (bat <= 15)
  {
   batIcon = 6;
   digitalWrite(A1, 1);
    delay(200);
    digitalWrite(A1, 0);
    delay(200);
  }
  else
  {
   digitalWrite(A1, 0);
  }
  
  if (bat < 0)
  {
   byte chigh = highByte(coldState);
   byte clow = lowByte(coldState);
   byte hhigh = highByte(hotState);
   byte hlow = lowByte(hotState);
    
   EEPROM.write(1, chigh);
   EEPROM.write(2, clow);
   EEPROM.write(3, hhigh);
   EEPROM.write(4, hlow);
    
   PowerOFF();
  }
   
lcd.clear();
lcd.setCursor(0,0);
lcd.print("XBC: ");
lcd.print(coldState);
lcd.setCursor(15, 0);
lcd.write(byte(batIcon));
  
lcd.setCursor(0, 1);
lcd.write(byte(7));
lcd.print("BC: ");
lcd.print(hotState);
  
  if (timer == 5)
  {
    digitalWrite(led, 1);
    delay(200);
    digitalWrite(led, 0);
    timer = 0;
  }
delay(500);
  // END //
}

void ColdChange()
  {
    coldState = coldState + 1;
  }   
  
void HotChange()  
  {
    hotState = hotState + 1;
  }

void Service()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Service Mode");
  Serial.println("==========");
  Serial.println("ENT SVC MD");
  Serial.println("==========");
  
svc:  String svcCmd = Serial.readString();
  if (svcCmd == "ext")
  {
  Serial.println("==========");
  Serial.println("EXT SVC MD");
  Serial.println("==========");
  
  lcd.clear();
  lcd.print("EXITING SVC MODE");
  delay(1000);
    
  return;
  }
  
  if (svcCmd == "h")
  {
    Serial.println("h - this help");
    Serial.println("sc - set cold status");
    Serial.println("sh - set hot status");
    Serial.println("ext - exit service mode");
    Serial.println("stat - show counters status");
    Serial.println("v - show version info");
  }
  
  if (svcCmd == "stat")
  {
    Serial.println("==========");
    Serial.print("COLD: ");
    Serial.println(coldState);
    Serial.print("HOT: ");
    Serial.println(hotState);
  }
  
  if (svcCmd == "sc")
  {
    Serial.println("==========");
    Serial.println("New COLD state: ");
    String newSc = Serial.readString();
    delay(3000);
    coldState = newSc.toInt();
    Serial.print("Cold State = ");
    Serial.println(coldState);
  }
  
  if (svcCmd == "sh")
  {
    Serial.println("==========");
    Serial.println("New HOT state: ");
    String newSh = Serial.readString();
    delay(3000);
    hotState = newSh.toInt();
    Serial.print("Hot State = ");
    Serial.println(hotState);
  }
  
  if (svcCmd == "v")
  {
    Serial.println("==========");
    Serial.print("Version Info: ");
    Serial.print(Version);
  }
  goto svc;
}

void PowerOFF()
{
pwr:
  digitalWrite(A1, 1);
  delay(200);
  digitalWrite(A1, 0);
  delay(200);
  goto pwr;
}

 

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

Вы чего-то не поняли в этой жизни.

Когда Вас просят показать код, значит, хотят его посмотреть, чтобы Вам помочь. Вы же своей "экономией места на сервере" создаёте дополнительные проблемы человеку, который Вам помочь хочет. Это, по-Вашему, хорошая идея? Не ведите себя так, как будто это Вас о чём-то попросили, а не Вы, и люди к Вам потянутся.

Надеюсь, Ваша "проблема" с long решена?

Всего хорошего!

Гриша
Offline
Зарегистрирован: 27.04.2014

intervision пишет:

 Решил не выкладывать простыню из вежливости и экономии времени читающего, и оказался виноват...

почитайте, как выкладывать код "вежливо" :))))) ставить номера строк и по номерам можно все обсудить... типа пост №хх строка уу. а простыни больше 10 строк сворачивать.