Проблемма в управлении с serial порта
- Войдите на сайт для отправки комментариев
Пнд, 17/06/2013 - 07:13
Собираю контроллер управления освещением для 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:

mode-='0';
Это что? необычный подход в преобразованиях строк в числа? Переделать и проверить.
Надо использовать класс String val = Serial.read()
А потом val.toInt()
или atoi() функцию
или Serial.parseInt()
mode-='0';
Это что? необычный подход в преобразованиях строк в числа? Переделать и проверить.
Надо использовать класс String val = Serial.read()
Serial.parseInt()
ТС, вам нужно
либо в программе, из которой вы отправляете цифру убрать отправку признака конца строки (10),
либо сделать проверку перед преобразованием:
либо использовать Serial.parseInt().
либо внимательно прочитайте что делает Serial.flush() и замените ее на
while(Serial.available()){ delay(2); Serial.read(); }Спасибо, я в программе убрал признак конца строки и в скетче добавил проверку перед преобразованием и всё заработало нормально.