Переменные через Serial

Mosh
Offline
Зарегистрирован: 24.03.2012

Здравствуйте. Подскажите как решить следующую проблему. Есть три переменных, public,int, имена a, b, c (для примера.) Требуется: При старте ардуинки, в терминал должно выводиться "Vvedi A". И ожидать ввода. Ввели А, нажали ENTER, потом "Vvedi B". И ожидать ввода.. Когда все три переменных будут заполнены, программа должна выполнять другие действия,(например моргать диодом с длительностью a) и не запрашивать больше ввода, до ресета. Есть такой код

int a, b, c, set;  
  
void setup(void)  
{  
  Serial.begin(9600);  
  pinMode(13,OUTPUT); 
}  

void loop(void)  
{   
  if(set==0) //ЕСЛИ SET не равен 1, то считываем переменные 
    { Serial.println("Vvedi A"); 
      a=readdata(); // назначаем а значение из функции readdata() 
      Serial.println("Vvedi B"); 
      b=readdata(); 
      Serial.println("Vvedi C"); 
      c=readdata(); 
      set=1; // Запрещаем более считывать переменные, и начинаем выполнять дальнейший код 
    } 

   Serial.print("Prisvoeno A "); 
   Serial.print(a, DEC); 
   Serial.println(); 
   Serial.print("Prisvoeno B "); 
   Serial.print(b, DEC); 
   Serial.println(); 
   Serial.print("Prisvoeno C "); 
   Serial.print(c, DEC); 
   Serial.println(); 
      
  digitalWrite(13, HIGH);   // set the LED on 
  delay(1000);              // wait for a second 
  digitalWrite(13, LOW);    // set the LED off 
  delay(1000);   
} 

int readdata() 
{ 
  byte x=0; 
  do 
   { 
    if (Serial.available()> 0) 
     { 
      delay (100); 
      x= Serial.read(); 
     } 
   }while(x==0); 
    
return x; 
}  

Но есть проблемы.
1. Вводимые переменные могут принимать значение от 0 до 32000
2. Код  кушает только один байт из Serial.read(), а из п.п 1 их может быть до 5 сразу.
3. На int назначается ASCII код символа, а не он сам.

Пробовал через массив char, но тоже не получилось. :(

int readdata() 
{ 
char* a ="{aaaaa}"; 
int i=0;  
  do 
  { 
    while(Serial.available()) 
     { 
      a[i] = Serial.read(); 
      i++; 
     } 
  }while(a[i] != '\0'); //Выполнять, пока не попадется ENTER 
    //}while(atoi(a)== 0); //Так тоже пробовал :( 
//a[i] = '\0'; 
Serial.print("Prinyato"); 
Serial.println(atoi(a),DEC); //переводим char в int и печатаем для теста 
return atoi(a); // Возвращаем значение функции, переводим char в int 
} 

 

chervyachok
chervyachok аватар
Offline
Зарегистрирован: 22.12.2011

 

unsigned long serialdata;
long incomeTime;
int inbyte;
int getPassWord = 0;
int passWordOK = 0;
int promtForPassword = 1;
int vaitForCommand = 1;
int getCommand = 0;

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

void loop()
{
	if (promtForPassword == 1 && passWordOK != 1){
		Serial.println("Enter password:");
		promtForPassword = 0;
		getPassWord = 1;
	}
	if (passWordOK == 1 && vaitForCommand == 1){
		Serial.println("1-set; 2-info; 9999-end; Enter command: ");
		vaitForCommand = 0;
		getCommand = 1;
	}
		getCommandNum();
}

void getCommandNum(){
	while (Serial.available() > 0){
		delay (3);	
		incomeTime = millis();	
		inbyte = Serial.read(); 
		serialdata = serialdata * 10 + inbyte - '0';
		if (Serial.available() == 1){
			if (serialdata == 111111 && getPassWord == 1){
				Serial.println("Password correct");
				passWordOK = 1;
				getPassWord = 0;
				Serial.flush();	serialdata = 0;	inbyte = 0;
			}
			if (serialdata != 111111 && getPassWord == 1){
				Serial.println("Password incorrect");
				promtForPassword = 1;
				Serial.flush();	serialdata = 0;	inbyte = 0;
			}
			if (serialdata == 1 && getCommand == 1){
				Serial.println("Select (1-26):");
				getCommand = 0;
				Serial.flush();	serialdata = 0;	inbyte = 0;
			}
		}	
	}		
	unsigned long CurrentMillis = millis();
	if(CurrentMillis - incomeTime >= 500) {
		Serial.flush();
		serialdata = 0;
		inbyte = 0;
	}
}

 У меня похожая задача. Вот часть кода. Понимаю что не идеально но работает.  

 inbyte - '0';" переводит из кода символа в сам символ.

Mosh
Offline
Зарегистрирован: 24.03.2012

Искал, ничего не нашел. Подумал, и написал.. Изменненая функция readdata() для моего кода выше. Пожалуйста пользуйте, кому нужно.

int readdata() //Эта функция возвращает начение переменной в int, введенной в Serialmonitor  
{
byte getByte;
int outByte=0;
 do
  {
    while(Serial.available()!=0)
     { 
      getByte=Serial.read()-48; // Вычитаем из принятого символа 48 для преобразования из ASCII в int
      outByte=(outByte*10)+getByte; //Сдвигаем outByte на 1 разряд влево, и прибавляем getByte 
      delay(500);// Чуть ждем для получения следующего байта из буфера (Чем больше скорость COM, тем меньше ставим задержку. 500 для скорости 9600, и приема 5-значных чисел)
     }
  }while (outByte==0); //Зацикливаем функцию для получения всего числа

Serial.flush(); //Вычищаем буфер (не обязательно)
return outByte;
}