STM32G031と内蔵ADCで電圧をソフトウェアシリアルに出力 3.300Vまで


x 必要がなかったから作らなかった。 アナログ入力は、5ピン
x adcは、0から1024
x 5/27 細か修正　清書等
x いちお書いておくが環境によつてはUART_DELAYの微調整

目的
主にGP2Y0A21YKの微小な電圧を測る。

説明
adcの値(4096)に6600掛けて8192で割ると3300にピッタリなる。

ピン配置
1 ソフトウェアシリアルTX
2,3 電源
4 リセット
5 アナログ入力
6 未使用
7,8 SWD

細かい修正

```c++


//#define in7 1 //uno
#define in7      PB7  // 1pin

#define DW   digitalWrite

//#define UART_DELAY 832 //  1200bps ok 031
#define UART_DELAY 102   //  9600bps ok 031

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

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

  DW(in7, HIGH);

    //q_st =  micros(); //debug

  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);

    //q_et =  micros(); //debug 引いた数が0で1041usなら正解

  return(0);

}//pc_putc

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

  //文字の中身がゼロか
  while(*str1){
  
    //一文字出力
    pc_putc(*str1 ++);
    //Serial.print( *str1 ++ ); //uno
  
  } //while

  //戻り値
  return(0);
}//pc_printf

//0から999まで文字列に変換
char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
  int a,b,c;

  b=l_num/10;
  c=l_num-(b*10); //1の桁
  a=b/10;         //100の桁
  b=b-(a*10);     //10の桁

  ch_hex_a_b[0] = '0' + a;
  ch_hex_a_b[1] = '0' + b;
  ch_hex_a_b[2] = '0' + c;
  ch_hex_a_b[3] = 0;

  return(ch_hex_a_b);
}//ch_hex_a

//初期化
void setup()
{
  //ポートをhiにする 初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);
  delayMicroseconds(UART_DELAY*10);

  //Serial.begin(9600);

} //setup

//メインループ
void loop()
{
  int s;   //101
  int ii;  //ループカウンター

  s = analogRead(A3); // PA11 PIN5
  //s = (65536/2)-1;
  //s = 65536/4;
  //s=(4096/2);

//d  //pc_printf( "," ); //debug_i
//d  String thisString1 = String(s);
//d  pc_printf( (char *)thisString1.c_str() );
//d  pc_printf("\r\n");

  //電圧に変換 ex 3.300 -> 3300 mVを出力
  s=(  (s*4)  *6600)>>13;

//d  //pc_printf( "," ); //debug_i
//d  String thisString2 = String(s);
//d  pc_printf( (char *)thisString2.c_str() );
//d  pc_printf("\r\n");

  //小数点以上と小数点以下を分ける iiは1の桁 sは小数点以上の桁
  ii = s;
  if     ( ii >= 3000 ) { ii = (ii - 3000); s = 3;}
  else if( ii >= 2000 ) { ii = (ii - 2000); s = 2;}
  else if( ii >= 1000 ) { ii = (ii - 1000); s = 1;}
  else                  {                 ; s = 0;}

  //電圧の小数点以上の表示
  ch_hex_a( s*10 );
  ch_hex_a_b[0] = '+';
//ch_hex_a_b[1] = '0' + s;
  ch_hex_a_b[2] = '.';      
  pc_printf(  ch_hex_a_b  );

  //電圧の小数点以下の表示
  pc_printf(  ch_hex_a(ii)  );

  //リターン
  pc_printf(  "\r\n"  );

  //1秒の待ち
  delay(1000);

} //loop



```



細かい修正前

```c++

#include <Wire.h>

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

//#define in7 1 //uno
#define in7      PB7  // 1pin

#define DW   digitalWrite

//#define UART_DELAY 832 //  1200bps ok 031
#define UART_DELAY 102   //  9600bps ok 031

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

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

  DW(in7, HIGH);

    //q_st =  micros(); //debug

  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);

    //q_et =  micros(); //debug 引いた数が0で1041usなら正解

  return(0);

}//pc_putc

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

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

        //一文字出力
        pc_putc(*str1 ++);
        //Serial.print( *str1 ++ ); //uno

    } //while

    //戻り値
    return(0);
}//pc_printf

//0から999まで文字列に変換
char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
  int a,b,c;

  b=l_num/10;
  c=l_num-(b*10); //1の桁
  a=b/10;         //100の桁
  b=b-(a*10);     //10の桁

  ch_hex_a_b[0] = '0' + a;
  ch_hex_a_b[1] = '0' + b;
  ch_hex_a_b[2] = '0' + c;
  ch_hex_a_b[3] = 0;

  return(ch_hex_a_b);
}//ch_hex_a


void setup()
{
  //ポートをhiにする 初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);
  delayMicroseconds(UART_DELAY*10);

  //while(1){pc_putc('A');delay(1000);} //debug
  //pc_printf("\r\nSTART\r\n"); //debug

  //Serial.begin(9600);

} //setup


int s;   //101
int ii;     //ループカウンタ

void loop()
{

  s = analogRead(A3); // PA11 PIN5
  //s = (65536/2)-1;
  //s = 65536/4;
  //s=(4096/2);

//d  //pc_printf( "," ); //debug_i
//d  String thisString1 = String(s);
//d  pc_printf( (char *)thisString1.c_str() );
//d  pc_printf("\r\n");


        //電圧に変換 ex 3.300 -> 3300 mVを出力
        s=(  (s*4)  *6600)>>13;

//d  //pc_printf( "," ); //debug_i
//d  String thisString2 = String(s);
//d  pc_printf( (char *)thisString2.c_str() );
//d  pc_printf("\r\n");



//小数点以上と小数点以下を分ける iiは1の桁 sは小数点以上の桁
int ii = s;
if     ( ii >= 3000 ) { ii = (ii - 3000); s = 3;}
else if( ii >= 2000 ) { ii = (ii - 2000); s = 2;}
else if( ii >= 1000 ) { ii = (ii - 1000); s = 1;}
else                  {                 ; s = 0;}

        //電圧の小数点以上の表示
        ch_hex_a( s*10 );
        ch_hex_a_b[0] = '+';
      //ch_hex_a_b[1] = '0' + s;
        ch_hex_a_b[2] = '.';      
        pc_printf(  ch_hex_a_b  );

        //電圧の小数点以下の表示
        pc_printf(  ch_hex_a(ii)  );

        //リターン
        pc_printf(  "\r\n"  );

  //1秒の待ち
  delay(1000);

} //loop




```

![soft_serial_adc_031_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e85a0273-d376-d49b-785b-1ce95e4c9231.jpeg)