PWM через Serial read

Sirocco
Offline
Зарегистрирован: 28.09.2013

Подскажите кусок кода, который мог бы передавать значение пришедшее в ком порт в функцию pwm.

Тоесть хочу передать в коп порт ардуино фразу R155, а она должна выполнить это:

analogWrite(10, RED);

где 10 - номер пина, RED значение шим, в данном случае равное 155.

Накидал такой код:

int RED = 0;

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

    pinMode (10, OUTPUT);

}

void loop()
{
     if (Serial.available()>3) 
    {   
       uint8_t inByte = Serial.read();   
        if(inByte=='r')
         { 
          RED = Serial.read();
          analogWrite(10, RED);
          Serial.print(RED);
         }
    }    
}

Но он не работает. Так как символы каким-то чудом преобразуются в коды символов, и в RED пишется полная чушь.

Как осилить? Когда-то раньше я видел реализацию, но так и не смог нагуглить.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
Sirocco
Offline
Зарегистрирован: 28.09.2013

У меня оно не работает. Просто не работает. Значения пинов не меняются, в ком порт ничего не выводит. Отсылаю, например, это: 100,111,200

std
Offline
Зарегистрирован: 05.01.2012
byte buffer,aout,val[3],length;

void setup(){
  Serial.begin(57600);
  pinMode( 9,OUTPUT);  // r
  pinMode(10,OUTPUT);  // g
  pinMode(11,OUTPUT);  // b
}

void loop(){
  buffer=0
  if(Serial.available()) buffer=Serial.read();

  if(buffer!=0){         // data waiting, working

    switch(buffer){      // assign out
      case 'r':
      case 'R':
        aout=9;
      break;
      case 'g':
      case 'G':
        aout=10;
      break;
      case 'b':
      case 'B':
        aout=11;
      break;
    }

    for(i=0;i<3;i++){       // read color
      if(!Serial.available() || Serial.peek()>'9' || Serial.peek()<'0') buffer=0;    // no digits or no data on serial
      if(Serial.available()){                         // normal data
        buffer=Serial.read()-48; // '0' = 48
        length++;
      }
      val[i]=buffer;
    }

    if(length==1){          // 1, shift >2
      val[2]=val[0];
      val[1]=0;
      val[0]=0;
    }
    if(length==2){          // 2, shift >1
      val[2]=val[1];
      val[1]=val[0];
      val[0]=0;
    }
    // for 3 bytes color, do nothing

    buffer=(val[0]*100)+(val[1]*10)+val[2];    // code color
    analogWrite(aout,buffer);                   // set color
                                               // report
    switch(aout){
      case  9: Serial.print('R=');break;
      case 10: Serial.print('G=');break;
      case 11: Serial.print('B=');break;
    }
    Serial.print(buffer,DEC);

  } // no data, do nothing  // if(buffer) ends
}                           // loop() ends

peek() проверяет следующий байт сериала, не читая его (не убирая из очереди)

Суть идеи - ждём некий байт, смотрим чё за буква. Буква обозначает нужный цвет в RGB. Потом читаем три байта, если читаются. Если прочиталось меньше, двигаем, так чтобы единица оказалась справа. Если читается что-то отличающееся от цифр или больше нету, считаем что ничего читать не надо. По дефолту нули. Потом остаётся умножить и записать в нужный выход. Номер выхода указали, когда читали букву.

Sirocco
Offline
Зарегистрирован: 28.09.2013

std, пока не компилируется, куча ошибок. Попробую поправить.

Sirocco
Offline
Зарегистрирован: 28.09.2013

Ваш код:

byte buffer,aout,val[3],length;
int i = 0;
void setup(){
  Serial.begin(57600);
  pinMode( 9,OUTPUT);  // r
  pinMode(10,OUTPUT);  // g
  pinMode(11,OUTPUT);  // b
}

void loop(){
  buffer=0;
  if(Serial.available()) buffer=Serial.read();

  if(buffer!=0){         // data waiting, working

    switch(buffer){      // assign out
      case 'r':
      case 'R':
        aout=9;
      break;
      case 'g':
      case 'G':
        aout=10;
      break;
      case 'b':
      case 'B':
        aout=11;
      break;
    }

    for(i=0;i<3;i++){       // read color
      if(!Serial.available() || Serial.peek()>'9' || Serial.peek()<'0') buffer=0;    // no digits or no data on serial
      if(Serial.available()){                         // normal data
        buffer=Serial.read()-48; // '0' = 48
        length++;
      }
      val[i]=buffer;
    }

    if(length==1){          // 1, shift >2
      val[2]=val[0];
      val[1]=0;
      val[0]=0;
    }
    if(length==2){          // 2, shift >1
      val[2]=val[1];
      val[1]=val[0];
      val[0]=0;
    }
    // for 3 bytes color, do nothing

    buffer=(val[0]*100)+(val[1]*10)+val[2];    // code color
    analogWrite(aout,buffer);                   // set color
                                               // report
    switch(aout){
      case  9: Serial.print('R=');break;
      case 10: Serial.print('G=');break;
      case 11: Serial.print('B=');break;
    }
    Serial.print(buffer,DEC);

  } // no data, do nothing  // if(buffer) ends
}                           // loop() ends

Отсылаю в порт r111, получаю в ответ 210530210531210530, с пинами ничего не происходит.

На всякий случай: Arduino IDE 1.0.5-r2, arduino Pro mini 

Sirocco
Offline
Зарегистрирован: 28.09.2013

Во, вроде работает:

char arrayR[3];
char arrayG[3];
char arrayB[3];
int r = 0, Red;
int g = 0, Green;
int b = 0, Blue;

void setup()
{
  Serial.begin(57600);
}
void loop()
{  

  if (Serial.available()>1) 
     {   
       uint8_t inByte = Serial.read();  
       
//===========RED=START========= 
        if(inByte=='R' || inByte=='r')
          { 
           if(Serial.available() > 0)
             {
               delay(5);
               while(r <= 2)
                {
                  arrayR[r] = Serial.read();
                  r++;
                }
               r = 0;
               Red = atoi(arrayR);
               analogWrite(9, Red);
               Serial.print("Red: ");
               Serial.println(Red);
               arrayR[r] = 0;
             }
          }
//===========RED==END==========
//=========GREEN=START=========
        if(inByte=='G' || inByte=='g')
          { 
           if(Serial.available() > 0)
             {
               delay(5);
               while(g <= 2)
                {
                  arrayG[g] = Serial.read();
                  g++;
                }
               g = 0;
               Green = atoi(arrayG);
               analogWrite(10, Green);
               Serial.print("Green: ");
               Serial.println(Green);
               arrayG[g] = 0;
             }
          }          
//=========GREEN==END==========
//==========BLUE==START========
        if(inByte=='B' || inByte=='b')
          { 
           if(Serial.available() > 0)
             {
               delay(5);
               while(b <= 2)
                {
                  arrayB[b] = Serial.read();
                  b++;
                }
               b = 0;
               Blue = atoi(arrayB);
               analogWrite(11, Blue);
               Serial.print("Blue: ");
               Serial.println(Blue);
               arrayB[b] = 0;
             }
          } 
//==========BLUE===END=========
     }

  delay(5);
}