정보나눔

오픈소스하드웨어 프로젝트에 대한 다양한 정보를 나누는 공간입니다.

AT명령어 사용하여 초음파센서값 thingspeak에 전송
닉닉닉 | 2018-06-25

현재 아두이노 우노 + esp8266(01)을 사용중에 있습니다.

 

2자리 3자리 센서값들은 정상적으로 thingspeak에 전송되는데 1자리 센서값이 전송되면

 

thingspeak가 0으로 인식하는 문제를 발견하였습니다. 시리얼 모니터 확인결과 한자리 값도 정상적으로 

 

프린트 합니다. 

 

소스 올리겠습니다. 수정해야할 부분 알려주시면 감사하겠습니다.

 

#include <SoftwareSerial.h>
#include <stdlib.h>
#define DEBUG true
#define ULTRASONIC_ECHO 8 
#define ULTRASONIC_TRIG 9
 
// 자신의 thingspeak 채널의 Write API key 입력
String apiKey = "HGJJA4DJG81BV6T5";
 
SoftwareSerial esp8266(2,3); // TX/RX 설정, esp8266 객체생성
 
void setup() {
  pinMode(ULTRASONIC_ECHO, INPUT); 
  pinMode(ULTRASONIC_TRIG, OUTPUT); // 초음파센서 활성화
  //시리얼통신속도 9600보드레이트 설정    
  Serial.begin(9600); 
  //소프트웨어 시리얼 시작
  esp8266.begin(9600);
  esp8266.println("AT+RST");
 
  /*AT 커맨드 이용*/
  sendData("AT+RST\r\n", 2000, DEBUG); //모듈을 리셋
  sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //dual mode로 설정
  sendData("AT+CWJAP=\"Hi\",\"53007257\"\r\n", 5000, DEBUG); //사용할 공유기 설정
}
 
void loop() {
  float ultrasonic_val =  Dist_cm();
  Serial.print("Ultrasonic : ");
  Serial.print(ultrasonic_val);
  Serial.println("cm");
 
  // String 변환
  char buf[16];
  String strVal = dtostrf(ultrasonic_val, 4, 1, buf);
  
  Serial.println(strVal);
  
  // TCP 연결
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += "184.106.153.149"; // api.thingspeak.com 접속 IP
  cmd += "\",80";           // api.thingspeak.com 접속 포트, 80
  esp8266.println(cmd);
   
  if(esp8266.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }
  
  // GET 방식으로 보내기 위한 String, Data 설정
  String getStr = "GET /update?api_key=";
  getStr += apiKey;
  getStr +="&field1=";
  getStr += String(strVal);
  getStr += "\r\n\r\n";
 
  // Send Data
  cmd = "AT+CIPSEND=";
  cmd += String(getStr.length());
  esp8266.println(cmd);
 
  if(esp8266.find(">")){
    esp8266.print(getStr);
  }
  else{
    esp8266.println("AT+CIPCLOSE");
    // alert uesp8266
    Serial.println("AT+CIPCLOSE");
  }
    
  // Thingspeak 최소 업로드 간격 15초를 맞추기 위한 delay
  delay(16000);  
}
 
//ESP8266의 정보를 알아내고 설정하기 위한 함수 선언
String sendData(String command, const int timeout, boolean debug){
  String response = "";
  esp8266.print(command); //command를 ESP8266에 보냄
  long int time=millis();
  
  while((time+timeout)>millis()){
    while(esp8266.available()){
      //esp가 가진 데이터를 시리얼 모니터에 출력하기 위함
      char c=esp8266.read(); //다음 문자를 읽어옴
      response+=c;
    }
  }
  if(debug){
    Serial.print(response);
  }
 
  return response;
}
 
uint16_t Dist_cm(void) //초음파센서 거리값 계산
{
  uint32_t timer = 0;
  uint16_t dist = 0;
  digitalWrite(ULTRASONIC_TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(ULTRASONIC_TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(ULTRASONIC_TRIG, LOW);
 
  timer = pulseIn(ULTRASONIC_ECHO,HIGH,24000);
  if(timer == 0)
    dist = 400;
  else
  {
    dist = timer * 0.034 / 2;
  }
  return dist;
}
프로필사진

수박쨈 2018-06-26 10:04:30

제가 작성자분께서 하시고자 하는 목적을 제대로 파악했는지 잘 모르겠지만
위 코드는 thingspeak에 초음파센서로 측정한 거리값을 보내는 코드가 맞는거죠??

 
보내는 코드가 맞다면 GET이 아닌 POST를 사용해보시는게 어떨까 싶네요.

 

 

그리고 dtostrf()에서 2번째 파라미터 값이 4인데 

만약 1자리의 데이터가 전달된다면 1자리가 비어있게 됩니다.

 

4자리의 데이터가 전달되야 하는데 2.0, 4.0 과 같은 데이터가 전달되면 소숫점 포함해서 3자리가 전달됩니다.

 

이 부분은 센서값이 저장되는 strVal의 길이를 strVal.length()로 측정해서 확인해보시면 좋을 듯 합니다.

 

그래서 이 문제때문에 쓰레기값이나 공란이 전달되기 때문에 thingspeak에서 정확한 숫자 데이터로 인지못하지 않나 싶네요.

프로필사진

닉닉닉 2018-06-26 14:16:49

답변해주셔서 감사드립니다.

strVal.length() 길이를 확인하여 만약 3자리가 전송된다면

if문을 사용하여 if(strval.length() == 3){}  이런식으로 예외처리를 하면 되는건지 궁금합니다.

 

프로필사진

수박쨈 2018-06-26 16:03:56

굳이 dtostrf()사용하여 센서값을 String으로 변환해야 하는지 문의드리고 싶네요.

 

단순하게 센서값을 String변환하여 전달되도 큰 문제는 없을거 같습니다.

프로필사진

닉닉닉 2018-06-26 18:59:10

으아... 빠른답변 감사드립니다.

시간되면 변환해서 한번 작동해보도록 하겠습니다.

추후에 안되는 점이 있으면 질문해도 될런지요...

 

이전글   |    네오픽셀이 안켜져요ㅜㅜ 2018-06-23
다음글   |    오렌지보드WIFI 타임아웃(TIME OUT)문제 어떻게 해결하나요? ... 2018-06-27