Проблемма в управлении с serial порта

danil0111
Offline
Зарегистрирован: 08.04.2013

Собираю контроллер управления освещением для LED лент на основе ардуино.

 

 

вот код:

int ledLevel_G=0; //яркость зеленого.
int ledLevel_R=0;//яркость красного.
int ledLevel_B=0;//яркость синего.
int ledLevel_W=0;//яркость белого.
int lightLevel=0; //уровень яркости света.
int NoiseLevel=0; //уравень шума.
//
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
//
long interval = 1000;
long interval2 = 100;
long interval3 = 1500;
// входы/выходы
int ledPin_G= 6;
int ledPin_R=5;
int ledPin_B=3;
int ledPin_W=9;
int switchPin = 2; // кнопка.
//
int mode=1;//режим


boolean lastButton = LOW;
boolean currentButton = LOW;
//
int temp=0;
int temp2=0;
boolean temp3=true;
 boolean temp4=true;  //
////  Функции режимов:


//Режим 1. Изменение яркости в зависимости от света на улице.
void mode_1(){


   ledLevel_G=0;
   ledLevel_R=0;
   ledLevel_B=0;



  lightLevel=analogRead(A1);//Считываем показания с сенсора освещения.
  lightLevel=constrain(lightLevel, 650, 1023);//
  ledLevel_W=map(lightLevel, 1023, 650, 255, 0);// Преобразовываем показания, и устанавливаем яркость.

}
//Режим 2. Включение "по хлопку"
void mode_2(){


   ledLevel_G=0;
   ledLevel_R=0;
   ledLevel_B=0;


  NoiseLevel=analogRead(A2);//Считываем уровень шума с микрофона.
  // Serial.println(NoiseLevel);
 unsigned long currentMillis1 = millis();//Считываем время с запуска программы.
  if(currentMillis1 - previousMillis1 > interval3) {
    temp3=true;
    previousMillis1 = currentMillis1;
  }
  if (temp3==true){
  if (NoiseLevel>100){
    temp++;
   if (temp==1) {
      ledLevel_W=100;
      }
   if (temp==2){
     ledLevel_W=0;
     temp=0;
     }
    temp3=false;
  }
  }
}
//Режим 3. Медленный мигающий режим.
void mode_3(){

  ledLevel_W=0; //выключаем основное освещение

 unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
  previousMillis = currentMillis;
  if (temp2==3){
    temp2=0;
  }
  temp2++;
  if (temp2==1){
     ledLevel_G=0;
      ledLevel_R=100;// включаем красный.
      ledLevel_B=0;

  }

  if (temp2==2){
    ledLevel_G=100;// включаем зеленый.
      ledLevel_R=0;
      ledLevel_B=0;

  }

  if (temp2==3){
    ledLevel_G=0;
      ledLevel_R=0;
      ledLevel_B=100;// включаем синий.

  }




  }
}
// Режим 4. Быстрый мигающий режим.
void mode_4(){
  ledLevel_W=0; //выключаем основное освещение
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval2) {
  previousMillis = currentMillis;
  if (temp2==3){
    temp2=0;
  }
  temp2++;
  if (temp2==1){
     ledLevel_G=0;
      ledLevel_R=100; //включаем красный.
      ledLevel_B=0;

  }

  if (temp2==2){
    ledLevel_G=100;// включаем зеленый
      ledLevel_R=0;
      ledLevel_B=0;

  }

  if (temp2==3){
    ledLevel_G=0;
      ledLevel_R=0;
      ledLevel_B=100;// включаем синий.

  }




  }
}
// Режим 5. Включение освещения в зависимости от громкости звука.
void mode_5(){
 NoiseLevel=analogRead(A2);// считываем показания с микрофона
  NoiseLevel=constrain(NoiseLevel, 0, 1023);// преобразуем.
  ledLevel_G=map(NoiseLevel, 1023, 0, 255, 0);
  ledLevel_R=map(NoiseLevel, 1023, 0, 255, 0);
  ledLevel_B=map(NoiseLevel, 1023, 0, 255, 0);
   ledLevel_W=map(NoiseLevel, 1023, 0, 255, 0);
}
void mode_6(){
ledLevel_G=0;
ledLevel_R=0;
ledLevel_B=0;
int ledLevel_W=0;
   NoiseLevel=analogRead(A2);//Считываем уровень шума с микрофона.

 unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval3) {
    temp3=true;
    previousMillis1 = currentMillis1;
  }
  if (temp3==true){
  if (NoiseLevel>100){
    temp++;
  }
  }
   switch (temp){
   case 1:
    ledLevel_R=100;
   break;
   case 2:
    ledLevel_G=100;
   break;
   case 3:
    ledLevel_B=100;
   break;
   default:
   temp=1;
   break;
 }
    temp3=false;


}


//функция для считывания показаний с кнопки исключая её дребезжание.
boolean debounce(boolean last)
{
  boolean current = digitalRead(switchPin);
  if (last==current)
  {

  }else {
   delay(5);
    current = digitalRead(switchPin);

  }
  return current;
}
//Установки:
void setup(){
  Serial.begin(9600);
 pinMode(switchPin, INPUT);
 pinMode(ledPin_G, OUTPUT);
 pinMode(ledPin_R, OUTPUT);
 pinMode(ledPin_B, OUTPUT);
 pinMode(ledPin_W, OUTPUT);
}
///////////

//Основной цикл
void loop(){




  currentButton = debounce(lastButton); // считываем показания с кнопки.
  if (lastButton == LOW && currentButton == HIGH) // если кнопка нажата
  {
  mode++; // изменяем режим.
 }

  lastButton = currentButton; //запоминаем предыдущее положение кнопки
unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > 1000) {
    temp4=true;
    previousMillis1 = currentMillis1;
  }
  if (temp4==true){
 temp4==false;
 
 
 
 if (Serial.available()!=0){

 mode=Serial.read();
 mode-='0';
 Serial.flush();
 }
 
 
 
  }
 
 
 Serial.print("mode is ");
 Serial.println(mode);
 
 switch (mode){ //выбор режима.
    case 1:
     mode_1();
     break;
     case 2:
     mode_2();
     break;
     case 3:
     mode_3();
     break;
     case 4:
     mode_4();
     break;
     case 5:
     mode_5();
     break;

//если не один режим не выбран тогда сбрасываем mode  на один.
  default:
  mode=1;
    }

   Serial.println(mode);

  
  analogWrite(ledPin_G, ledLevel_G);
  analogWrite(ledPin_R, ledLevel_R);
  analogWrite(ledPin_B, ledLevel_B);
  analogWrite(ledPin_W, ledLevel_W);
}

Пробема в том что когда с компа отправляешь номер режима, режим включается на какое-то время (доли секунды),а потом значение режима(mode) становится -38.

всё норм:

Посылаем 3:

 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

mode-='0';

Это что? необычный подход в преобразованиях строк в числа? Переделать и проверить.

Надо использовать класс String val = Serial.read()

А потом val.toInt()

или atoi() функцию

или Serial.parseInt()

maksim
Offline
Зарегистрирован: 12.02.2012

NeiroN пишет:

mode-='0';

Это что? необычный подход в преобразованиях строк в числа? Переделать и проверить.

Нет, это вполне нормальный подход преобразования символа в цифру.

NeiroN пишет:

Надо использовать класс String val = Serial.read()

Такая конструкция не будет формировать строку с числом ,а также будет сохранять только последний прочитанный символ.

NeiroN пишет:

Serial.parseInt()

А вот это в самый раз, если нужно число, а не цифра, но и для цифры тоже пойдет.

ТС, вам нужно
 либо в программе, из которой вы отправляете цифру убрать отправку признака конца строки (10), 
 либо сделать проверку перед преобразованием:

 mode=Serial.read();
 if(mode >= 48 && mode <= 57)mode-='0';

 либо использовать Serial.parseInt().
 либо
 внимательно прочитайте что делает Serial.flush() и замените ее на

while(Serial.available()){
 delay(2);
 Serial.read();
}

 

danil0111
Offline
Зарегистрирован: 08.04.2013

Спасибо, я в программе убрал признак конца строки и в скетче добавил проверку перед преобразованием и всё заработало нормально.