2017-04-13 3 views
0

시리얼에서 명령이 들어올 때까지 기다렸다가 데이터에 따라 led 색상을 변환하는 애플리케이션을 작성하고 있습니다. 명령 (더 RTOS) 받았다 없을 때 MBed RTOS가 시리얼에 응답하지 않습니다.

  • 변경 색상을 직접 주도 LED 색상 변경 직렬 연결
  • 이상

    1. 잡 및 전송 명령 : I는 각각 자신의 오른쪽에서 작업 요소를 가지고있다.

    새로운 데이터가 도착할 때까지 LED 루프가 작동해야합니다. 그러나 RTOS 라이브러리의 스레드를 사용하면 LED가 변경되지 않습니다. 이것은 내가 내 코드와 RTOS에 문제가 있다고 생각하게한다. 문제는 무엇이 문제인지를 파악할 수 없다는 것이다.

    디버깅 (직렬을 통해 PC로 문자열 인쇄)에서 스레드가 실행 중이고 루핑되는 것을 볼 수 있습니다. 변수가 만들어 질 때 설정된 값을 사용합니다. 메인 스레드는 콘솔에 출력이 없거나 시리얼 입력을 읽지 못하는 것으로 보입니다.

    스레드를 시작하지 않으면 직렬 통신이 다시 작동하여 문제가 내 코드와 RTOS 라이브러리에 있음을 확인합니다.

    다른 포럼 및 게시물 읽기에서 나는 직렬 및 RTOS에서 문제가 될 수 있으며 모든 printf 기능을 제거하고 RawSerial로 변경한다는 제안을 읽었습니다.하지만이 작업은 아무 것도하지 않습니다.

    은 정말

    #include "mbed.h" 
    #include "rtos.h" 
    #include "xbee.h" 
    #include "CMDLIB.h" 
    #include "WS2812.h" 
    #include "PixelArray.h" 
    
    #define LED_COUNT1 134 
    #define OUT_WHEEL 28 
    
    char startChar = '$'; 
    char endChar = ';'; 
    
    Serial pc(USBTX, USBRX); // tx, rx 
    
    CMDLIB cmd; 
    xbee xbee(p28, p27, p29, 38400); 
    PixelArray px1(LED_COUNT1); 
    WS2812 set1(p5, 144, 3, 11, 10, 11); 
    Thread ledthread; 
    
    int ledFunction; 
    int colour1[3], colour2[3], speed, intensity; 
    
    //LED Functions 
    void offLED() 
    { 
        for(int i = 1; i < LED_COUNT1; i++) 
        { 
         px1.Set(i, 0x000000); 
        } 
        set1.write(px1.getBuf()); 
    } 
    
    void solidPulse(int colour, int speed, int intensity) 
    { 
        px1.SetAll(colour); 
        //pc.printf("2\r\n"); 
        set1.write(px1.getBuf()); 
        //pc.printf("3\r\n"); 
        for(int a = 255; a > intensity; a--) 
        { 
         px1.SetAllI(a); 
         set1.write(px1.getBuf()); 
         wait_ms(speed); 
         //pc.printf("%d,",a); 
        } 
        //pc.printf("\r\n4\r\n"); 
        for(int a = intensity; a < 255; a++) 
        { 
         px1.SetAllI(a); 
         set1.write(px1.getBuf()); 
         wait_ms(speed); 
         //pc.printf("%d,",a); 
        } 
        //pc.printf("\r\n5\r\n"); 
    
    } 
    
    void ledThread() 
    { 
        while(1) 
        { 
         switch(ledFunction) 
         { 
          case 0: //Off 
           //offLED(); 
          break; 
          case 1: //Solid 
           //pc.printf("1\r\n"); 
          solidPulse(cmd.RGB2HEX(colour1[0], colour1[1], colour1[2]), speed, intensity); 
          break; 
          case 2: //Solid Pulse 
          solidPulse(cmd.RGB2HEX(colour1[0], colour1[1], colour1[2]), speed, intensity); 
          break; 
          default: 
          break; 
         } 
         //pc.printf("%d;\r\n", ledFunction); 
         wait_ms(200); 
        } 
    } 
    
    void setup() 
    { 
        set1.useII(WS2812::PER_PIXEL); // use per-pixel intensity scaling 
        xbee.setup(startChar, endChar); 
        pc.baud(38400); 
        muxcon = 0; 
        ledFunction = 0; 
        for(int j = 0; j < 3; j++) 
        { 
         colour1[j] = 1; 
         colour2[j] = 1; 
        } 
        speed = 100; 
        intensity = 0; 
    
        for(int i = 0; i < LED_COUNT1; i++) 
        { 
         px1.Set(i, 0xffffff); 
        } 
        set1.write(px1.getBuf()); 
    } 
    
    char * convertChar(string data) 
    { 
        char * chars = ""; 
        for(int k = 0; k < data.size(); k++) 
        { 
         chars += data[k]; 
        } 
        return chars; 
    } 
    
    int main() 
    { 
        setup(); 
        ledthread.start(ledThread); 
        string recData; 
        while(true) 
        { 
         if(xbee.readable()) 
         { 
          recData = xbee.readData(); 
          //pc.printf("Recieved Data: %s\r\n",recData); 
          string cmdString = cmd.getCommand(recData); 
          if(cmdString == "[TEL]") 
          { 
           gatherTelemetry(); 
           string telResult = cmd.formatTelemetry(sData1, sData2, sData3, sData4, sData5, sData6); 
           xbee.sendData(telResult); 
          } 
          if(cmdString == "[LED]") 
          { 
           //pc.printf("[RES],LED;\r\n"); 
    
           string res[10]; 
           int count = 0; 
           char c; 
           for(int j = 0; j < recData.size(); j++) 
           { 
            c = recData[j]; 
            if(c == ',' || c == ';') 
            { 
             count++; 
            } 
            else 
            { 
             res[count] += c; 
            } 
           } 
           ledFunction = atoi(res[1].c_str()); 
           colour1[0] = atoi(res[2].c_str()); 
           colour1[1] = atoi(res[3].c_str()); 
           colour1[2] = atoi(res[4].c_str()); 
           colour2[0] = atoi(res[5].c_str()); 
           colour2[1] = atoi(res[6].c_str()); 
           colour2[2] = atoi(res[7].c_str()); 
           speed = atoi(res[8].c_str()); 
           intensity = atoi(res[9].c_str()); 
           //pc.printf("Raw Values: %s-%s-%s-%s-%s-%s-%s-%s-%s-%s\r\n",res[0],res[1],res[2],res[3],res[4],res[5],res[6],res[7],res[8],res[9]); 
           //pc.printf("Converted: %d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",ledFunction,colour1[0],colour1[1],colour1[2],colour2[0],colour2[1],colour2[2],speed,intensity); 
    
    
           xbee.sendData("[RES],OK"); 
    
           //solidPulse(cmd.RGB2HEX(colour1[0], colour1[1], colour1[2]), speed, intensity); 
          } 
          if(cmdString == "[CMD]") 
          { 
    
          } 
         } 
        } 
    } 
    
  • 답변

    2

    wait_ms 기능은 대기 상태로 실행중인 스레드를 넣지 않고 다른 스레드의 실행을 허용하지 않는 의도 한대로 작동 코드를 얻으려면 어떤 도움을 주셔서 감사합니다. 따라서 ledThread은 결코 제어를 포기하지 않습니다. 대신 ledThread는 Thread::wait을 호출해야합니다. 이는 현재 스레드를 대기 상태로 만들고 다음 준비 스레드가 실행되도록합니다.

    while 루프를 제어하지 않고 ledThread를 다시 실행할 수있게하려면 main while 루프를 변경해야 할 수도 있습니다.

    +0

    어떻게 메인 스레드가 제어 대기 스레드를 대기하게합니까? – NoLiver92

    +1

    @ NoLiver92 : 그건 하나의 방법이지만, RTOS에서 실행할 수있는 가장 우선 순위가 높은 작업이 실행됩니다. _blocked_가 아닌 작업은 실행할 수 있습니다. 'Thread :: wait'는 블로킹의 가장 간단한 방법이지만 들어오는 명령에 대한 진정한 실시간 응답을 허용하지 않습니다. 더 좋은 접근 방법은'xbee'에서 블로킹 대기를하는 것입니다. 이것은'xbee' 클래스가 mBed RTOS를 인식하도록 요구합니다. 즉,'xbee :: readable()'를 대체 할 블로킹 대기 시간이 필요합니다. 'xbee :: readable'를 주기적으로 폴링해도 문제가되지 않지만, 즉각적인 실시간 응답이 필요한 경우에는 폴링이 부적절 할 수 있습니다. – Clifford

    관련 문제