2012-04-16 2 views
1

Arduino를 사용하여 Pachube에 데이터를 게시 할 때 문제가 있습니다. Arduino는 't'를 보내고 'l'을 보낼 때 빛의 레벨에 대한 JSON 데이터를 반환 할 때 온도에 대한 JSON 데이터를 반환하도록 구성됩니다. 이것은 Arduino 시리얼 모니터를 통해 완벽하게 작동합니다. 나는 두 개의 bash 스크립트를 만들었다. 하나는 정기적으로 't'와 'l'명령을 Arduino에 보내고 각 요청 사이에 10 초를 기다립니다.Arduino가 쿼리보다 많은 응답을 반환했습니다.

while true; do 
    echo -n t > /dev/ttyACM0 
    echo "$(date): Queried Arduino for temperature." 
    sleep 10 
    echo -n l > /dev/ttyACM0 
    echo "$(date): Queried Arduino for light." 
    sleep 10 
done 

잘 작동합니다. 10 초마다 에코 메시지가 나타납니다. 다른 스크립트는 직렬 포트에서 생성 된 JSON을 읽습니다 (기본적으로 일부 웹 페이지에서 복사했습니다). 이 매 10 초 (첫 번째 스크립트가 JSON 메시지를 작성하는 아두 이노 말했다 때마다 그것을 할 만해야하지만

ARDUINO_PORT=/dev/ttyACM0 
ARDUINO_SPEED=9600 
API_KEY='MY_PACHUBE_KEY' 
FEED_ID='MY_FEED_ID' 

# Set speed for usb 
stty -F $ARDUINO_PORT ispeed $ARDUINO_SPEED ospeed $ARDUINO_SPEED raw 
exec 6<$ARDUINO_PORT 

# Read data from Arduino 
while read -u 6 f ;do 
    # Remove trailing carriage return character added 
    # by println to satisfy stupid MS-DOS Computers 
    f=${f:0:${#f} - 1} 

    curl --request PUT --header "X-PachubeApiKey: $API_KEY" --data-binary "{ \"version\":\"1.0.0\", \"datastreams\":[ $f ] }" "http://api.pachube.com/v2/feeds/MY_FEED_ID" 
    echo "$(date) $f was read." 
done 

불행하게도,이 스크립트는 에코 메시지 나에게이 Pachube에 게시 된 데이터를 10 초당 여러 번 이야기에 미친 간다). Arduino에서 버퍼링 된 메시지가 문제가 될 수 있다고 생각했지만 문제를 다시 껐다가 다시 켤 때도 마찬가지입니다. 이견있는 사람? 미리 감사드립니다.

답변

1

내가 볼 몇 가지 일반적인 것들을 아두 이노와 당신이하고있는 다른 것들의 소수 완전히 익숙하지 오전하지만 현재 위치 :

  • 배쉬 안정적 이진 데이터를 처리 할 거의 불가능하다. 배쉬 문자열에 NUL 바이트를 저장할 방법이 없습니다. 당신이 임의의 데이터를 읽을 수있게하기 위해 속임수를 쓰려고 노력하고있는 것처럼 보입니다. 문자 데이터를 read에 보내고 싶다면 그렇지 않을 것입니다.

  • read은 개행 문자로 구분 된 입력 (또는 bash가 충분히 새로운 경우 제공된 값 -d)을 읽습니다. while 루프가 읽는 형식을 모르지만 개행 문자로 분리 된 문자열이어야합니다.

  • read -r을 사용하십시오. 이스케이프 시퀀스를 해석하지 않으려면 read -r을 사용하십시오. (거의 항상 -rread으로 지정해야합니다.)

  • 각 문자열의 끝에서 문자를 무조건적으로 스트립하는 것이 가장 좋지 않습니다. 나는 다음을 사용합니다 : f=${f%+($'\r')}, 하나 또는 그 이상 인접한 \r을 f의 끝에서 제거합니다. 기본값이 아닌 경우 스크립트 맨 위에 shopt -s extglob을 기억하십시오.

  • 실제로 문제가되지 않아야하지만 실제로 필요하지 않는 한 exec을 사용하지 않는 것이 좋습니다. 여기에는없는 것입니다. done <$ARDUINO_PORT을 넣고 while 루프를 종료하고 read에서 -u 6 인수를 제거하십시오 (루프 내부에있는 특정 항목이 stdin에서 명확하게 읽히고 충돌 할 수는 없지만 대소 문자는 아닙니다). 열려있는 FD는 루프를 종료 할 때 자동으로 닫힙니다.

  • 예약되어 있고 환경의 변수와 충돌 할 수 있기 때문에 모든 대문자 변수 이름을 스크립트에 만들지 마십시오. 최소한 하나의 소문자를 사용하십시오. 물론이 변수가 시스템의 무언가에 의해 설정되고 사용자가 사용하거나 수정하는 경우에만 적용됩니다.

+0

많은 도움을 주셔서 감사합니다. 나는 그들이 행동에 변화가 생기고 몇 가지 피드백을 주는지 볼 것입니다. – mikey

+0

안녕하세요. 불행히도 귀하의 제안 중 아무도 도움이되지 않았습니다. 어쨌든 고마워. 다른 아이디어? – mikey

+0

'set -x'를 사용하여 디버깅을 시도해 루프 진행을 결정하는 것이 무엇입니까? 그냥 "여러 번"기다렸다가 무언가를 받기를 기다리거나 아무것도 기다리지 않는 단단한 루프에서 뛰고 있습니까? – ormaaj