STM32G031とS-5851Aで温度をシリアルに出力(ソフトウェアシリアル)(STM32)(Arduino)



x あまり正確では、ない


目的
秋月で売っている安価なS-5851A(約110円)を使って温度を出力する。


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり



![o_con278.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/80469e63-129e-4f9b-7d01-88fd12170a32.jpeg)


![o_con280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8422f842-fec4-2c90-66f3-ef76efdaaa8c.jpeg)




```c++



//I2C_5851_H_031_1
#include <Arduino.h>
#include <Wire.h>

//STM32G031J6M6 i2cピンの定義
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

#define S5851A 0x48

#define in7      PB7  // 1pin

#define DW   digitalWrite

#define UART_DELAY 102   //  9600bps ok 031

//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)


//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

  DW(in7, HIGH);

  DW(in7, LOW);//START
  delayMicroseconds(UART_DELAY);

  for (int ii = 0; ii < 8; ii++) {
    DW(in7, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY);
  }//for

  DW(in7, HIGH);//Stop
  delayMicroseconds(UART_DELAY);

  return (0);

}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    pc_putc(*str1 ++);

  } //while

  //戻り値
  return (0);

}//pc_printf


//初期化
void setup()
{

  //ポートをhiにする 初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);

  //i2cの初期化
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

} //setup


//メインループ
void loop()
{

  int s; //センサーの値  //101
  int n0; //温度　小数点以上
  char data_read[8]; //バッファー

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

  //温度の読み込み
  s = 99;
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    s = (int)Wire.read();       // 1バイトを受信
  }//while
  delay(1);

  //温度の表示
  data_read[0] = '0' + DIV10(s);                   // '0'+(s/10)
  data_read[1] = '0' + (  s - (DIV10(s) * 10)  );  // '0'+(s%10)
  data_read[2] = '\r';
  data_read[3] = '\n';
  data_read[4] = 0;
  pc_printf(data_read); //010
  //1秒の待ち
  delay(1000);

} //loop



```



PA0がソフトウェアシリアルのバージョン
x OB(オプションビット)をリセットからGPIOにしておく
x 出来ればnBOOT_SELのチェックも外しておく


![o_con279.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a0382689-3f89-332c-9a27-458f93c181cd.jpeg)


![o_con281.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/88294a74-35f7-be1e-276f-baeeaad38ead.jpeg)


![o_con283.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0f4b9f12-6574-762a-d9db-974be3bb559a.jpeg)



xなぜか知らないがI2Cは、古いバージョンだと動く

![o_con282.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f6c50f1e-d66a-3f46-d02a-9b8dcf2101be.jpeg)



```c++


//I2C_5851_H_PA0_031_1
#include <Arduino.h>
#include <Wire.h>

//STM32G031J6M6 i2cピンの定義
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

#define S5851A 0x48

#define in7      PA0  // 1pin

#define DW   digitalWrite

#define UART_DELAY 102   //  9600bps ok 031

//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)


//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

  DW(in7, HIGH);

  DW(in7, LOW);//START
  delayMicroseconds(UART_DELAY);

  for (int ii = 0; ii < 8; ii++) {
    DW(in7, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY);
  }//for

  DW(in7, HIGH);//Stop
  delayMicroseconds(UART_DELAY);

  return (0);

}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    pc_putc(*str1 ++);

  } //while

  //戻り値
  return (0);

}//pc_printf


//初期化
void setup()
{

  //ポートをhiにする 初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);

  //i2cの初期化
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

} //setup


//メインループ
void loop()
{

  int s; //センサーの値  //101
  int n0; //温度　小数点以上
  char data_read[8]; //バッファー

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

  //温度の読み込み
  s = 99;
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    s = (int)Wire.read();       // 1バイトを受信
  }//while
  delay(1);

  //温度の表示
  data_read[0] = '0' + DIV10(s);                   // '0'+(s/10)
  data_read[1] = '0' + (  s - (DIV10(s) * 10)  );  // '0'+(s%10)
  data_read[2] = '\r';
  data_read[3] = '\n';
  data_read[4] = 0;
  pc_printf(data_read); //010
  //1秒の待ち
  delay(1000);

} //loop


```