LoginSignup
2
5

More than 3 years have passed since last update.

ラズベリーパイとESP32で温度管理システムの制作(2) 送信デバイス制作

Posted at

ラズベリーパイに温湿度データを送信するデバイスの作成です。

全体のレイアウト

ユニバーサル基板に部品をはんだ付けしています。
image.png

回路

SHT31とssd1306を並列でi2c接続します。
とはいっても4つの線を並列に繋ぐだけ。簡単簡単。

image.png

i2cアドレスの確認

配線が決まったらブレッドボードでアドレスの確認をします。
コードはこのページを参照しました。

コードを走らせて、出てきたアドレスをメモします。
この場合は、SHT31が0x45、ssd1306が0x3Cでした。

ESP32に書き込む

/*
 * =========WiFi Config==========
*/
#include "WiFi.h"
#include "AsyncUDP.h"
#include <stdio.h>

const char * ssid = "ssid";
const char * password = "ssidのパスワード";

//IPアドレスは複数のESP32全て同一にします。
AsyncUDP udp;
IPAddress ESP32_ip(192,168,x,x);
IPAddress server_ip(192,168,x,x);
IPAddress gateway(192,168, x, x);
IPAddress subnet(255, 255, 255, 0);
IPAddress DNS(192, 168, x, x);

//ESP32に固有番号を振る
int deviceNo = 1;

#define ssd1306_Address 0x3C  //ssd1306のi2cアドレス
#define SHT31_Address  0x45  // SHT31のI2Cアドレス

WiFiServer server(80);

const int LEDPIN = 2;
const int PORTNO = 1234;
/*
 * =========SHT31 Config==========
*/
#include <SPI.h>
#include <Arduino.h>
#include <Wire.h>
#include "AE_SHT31.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example



// SHT31のアドレスを設定
AE_SHT31 SHT31 = AE_SHT31(SHT31_Address);

float temp,humi;


/*
 * =========SeepSleep Config==========
*/

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  9     /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}






void setup() {
  // シリアル通信を9600bpsに設定
  Serial.begin(9600);

  // シリアルに文字を出力
  // SHT31をソフトリセット
  SHT31.SoftReset();
  // 内蔵ヒーター 0:OFF 1:ON
  SHT31.Heater(0);

  if(!display.begin(SSD1306_SWITCHCAPVCC,ssd1306_Address )) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  display.clearDisplay();

  //ssd1306の表示設定
  display.drawPixel(10, 10, WHITE);
  display.setTextSize(2);
  display.setTextColor(WHITE);

   temp = SHT31_TEMP();
   humi = SHT31_HUMI();

/*
 * =========ディスプレイ表示==========
*/

   display.clearDisplay();
   display.setCursor(0,0);
   display.print(" "); 
   display.print(temp); 
   display.println(" 'C");

   display.print(" "); 
   display.print(humi); 
   display.println(" %"); 

   display.display();
/*
 * =========WiFi Setup==========
*/

   pinMode(LEDPIN,OUTPUT);

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);

    WiFi.config(ESP32_ip, gateway, subnet, DNS); 

    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("WiFi Failed");
        while(1) {
            delay(1000);
        }
    }

    if(udp.connect(server_ip, PORTNO)) {
        Serial.println("UDP connected");
        udp.onPacket([](AsyncUDPPacket packet) {
            Serial.print("UDP Packet Type: ");
            Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
            Serial.print(", From: ");
            Serial.print(packet.remoteIP());
            Serial.print(":");
            Serial.print(packet.remotePort());
            Serial.print(", To: ");
            Serial.print(packet.localIP());
            Serial.print(":");
            Serial.print(packet.localPort());
            Serial.print(", Length: ");
            Serial.print(packet.length());
            Serial.print(", Data: ");
            Serial.write(packet.data(), packet.length());
            Serial.println();
            //reply to the client
            packet.printf("Got %u bytes of data", packet.length());
        });


    }

}



void loop()
{

   temp = SHT31_TEMP();
   humi = SHT31_HUMI();

/*
 * =========ディスプレイ表示==========
*/

   display.clearDisplay();
   display.setCursor(0,0);
   display.print(" "); 
   display.print(temp); 
   display.println(" 'C");

   display.print(" "); 
   display.print(humi); 
   display.println(" %"); 

   display.display();

/*
 * =========UDP送信==========
*/
//dtostrf(変換する値,変換後の総文字数,小数点以下の桁数,変換後格納する変数);

    char udpStr1[6];
    char udpStr2[6];
    char buf[10];

    dtostrf(temp,5,2,udpStr1);
    dtostrf(humi,5,2,udpStr2);

    sprintf(buf,"%d,%s,%s",deviceNo,udpStr1,udpStr2);
    Serial.println(buf);

    udp.broadcastTo(buf, PORTNO);

/*
 * =========後処理==========
*/

   Ltika();
   ESP32_Sleep(10*60);
}

/*
 * =========SHT31の温湿度取得==========
*/

float SHT31_TEMP(){
    // SHT31から温度データを取得
  SHT31.GetTempHum();
  return SHT31.Temperature();
}

float SHT31_HUMI(){
    // SHT31から湿度データを取得
  SHT31.GetTempHum();
  return SHT31.Humidity();
}

/*
 * =========ESP32 DeepSleep==========
*/

void ESP32_Sleep(int sleepime){

  delay(1000); //Take some time to open up the Serial Monitor
  ++bootCount;

  print_wakeup_reason();

  esp_sleep_enable_timer_wakeup(sleepime * uS_TO_S_FACTOR);
  esp_deep_sleep_start();

}

/*
 * =========Lチカ==========
*/

void Ltika(){    
    for (int i=0;i<3;i++){
      digitalWrite(LEDPIN,HIGH);
      delay(100);
      digitalWrite(LEDPIN,LOW);
      delay(100);
    }
}

204行目の、sprintf(buf,"%d,%s,%s",deviceNo,udpStr1,udpStr2); 
でデバイスNo・温度・湿度のデータをカンマ区切りでまとめて送信しています。
これは後にUDP受信した後に、ポジション毎にデータを振り分ける為です。

起動

マイコンに書き込み、起動すると、ディスプレイに温湿度が表示されます。
通信に成功すると、ESP32ボード上の青色LEDが3回点滅します。
image.png

次はラズベリーパイ側の記事を書く予定です。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5