電圧計を作る ③ ADS8699のスケッチ その2 アナログ電圧の読み出し

 前回、12.288 ~–12.288Vが入力範囲のデフォルトから、6.144~–6.144Vの入力レンジであるRANGE_SEL_REG Register (address = 14h)を0010bに変更しました。この状態で、入力電圧を読みます。

下位バイトを読めない

 18ビットのデータは、DATAOUT_CTL_REG RegisterのD[31:14] に入っています。D[31:16]は、上位16ビットを読むとえられますが、残りの2ビットは下位16ビットを読まないとえられません。しかし、読めません。

 TI社のQ&A(ADS8691: how to read register value of bit[0:15])に、次のように書かれています。

Here is an example to use READ_HWORD command to read the 16-bit of ALARM_H_TH_REG Register:

(Byte 0 Address for bits 7-0 = 24h, Byte 1 Address for bits 15-8 = 25h, Byte 2 Address for bits 23-16 = 26h, Byte 3 Address for bits 31-24 = 27h)

  1. Use Read_HWORD command to read the 16-bit (0~15 bit) of register:

             Data frame:         <11001_xx> <0_0010_0100><00000000><00000000>

  1. Use Read_HWORD command to read the 16-bit (16~31 bit) of register:

             Data frame:         <11001_xx> <0_0010_0110><00000000><00000000>

Please note:

A “0” should be added prior to the address to have a 9-bit address: 0_0010_0100b for address 24h.

LSB of the 9-bit address is always ignored and considered as 0b.

To write/read both byte 0 and byte 1(or byte 2 and byte 3) in one command, the low byte address (byte 0 or 2) should be used. If the address of byte 1 or 3 is given, the LSB (bit 0) will be ignored, because it is a 16 bit address now.

HWORD commands can be only written to the addresses of byte 0+byte 1 or byte 2+byte 3 and so on. They cannot be used for byte 1+ byte 2.

 しかし、読めませんでした。

スケッチ

 16ビットを読む形で、スケッチを書きました。試行を何度も行ったので、少し冗長な記述になっています。


#include <SPI.h> 
#define CS  9
#define RST 8
const float LSB = 46.875;  // 1.5V x Vref 0010b
//ADS8699
SPISettings settings(10000000, MSBFIRST, SPI_MODE0);

void setup() {
  pinMode(RST, OUTPUT);
  digitalWrite(RST, HIGH);  // reset
  delay(0.1);
  digitalWrite(RST, LOW);
  delay(0.1);
  digitalWrite(RST, HIGH);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  Serial.begin(9600);
  while(!Serial);
  Serial.println("\nADS8699 test");
  SPI.begin();
        Serial.println("\write DATAOUT_CTL_REG Register---- ");
        SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
            uint8_t highByte = SPI.transfer(0b1101000); // 11010_00_ LS DATAOUT_CTL_REG Register
            uint8_t midByte  = SPI.transfer(0b00010000); // 0x10 _0
            uint8_t  lowByte = SPI.transfer(0x00);  // 
            uint8_t  lowlowByte= SPI.transfer(0b00000000);  // real data
        digitalWrite(CS, HIGH);
        delay(0.2);
      Serial.println("\write range ------ ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highByte = SPI.transfer(0b11010100); // 11010_10_ LS
             midByte =  SPI.transfer(0b00101000); // 0x14 _0
              lowByte = SPI.transfer(0x00);  // 
              lowlowByte = SPI.transfer(0b00000010);  // 
        digitalWrite(CS, HIGH);
        SPI.endTransaction();
        delay(0.2);
}

int read_range(){
  Serial.print("\nread range ------ ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
            uint8_t highByte = SPI.transfer(0b11001000); // 11001_xx_ read range1
            uint8_t midByte =  SPI.transfer(0b00101000); // 14
            uint8_t  lowByte =  SPI.transfer(0x00);  // 
            uint8_t  lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    delay(0.2);
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highByte = SPI.transfer(0b11001000); // 11001_xx_ read range2
             midByte =  SPI.transfer(0b00101000); // 14
              lowByte = SPI.transfer(0x00);  // 
              lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    Serial.print(highByte,BIN);Serial.println(midByte,BIN);
    Serial.print(highByte,HEX);Serial.print("," );
    Serial.print(midByte,HEX); //Serial.print("," );
    Serial.println("-" );

    //  Serial.print("\nread range 1byte------ ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highByte = SPI.transfer(0b01001000); // 11001_xx_ read range1
             midByte =  SPI.transfer(0b00101000); // 14
              lowByte =  SPI.transfer(0x00);  // 
              lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    delay(0.2);
      Serial.print("\nread range 1byte------ ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highByte = SPI.transfer(0b01001000); // 11001_xx_ read range1
             midByte =  SPI.transfer(0b00101000); // 14
              lowByte =  SPI.transfer(0x00);  // 
              lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    Serial.println(highByte,BIN);
    Serial.print(highByte,HEX);Serial.print("," );
    Serial.println(midByte,HEX); //Serial.print("," );
    delay(0.2);
}

double read_voltdata( ) {
  Serial.println("\nread voltage ------");
    SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
          uint8_t   highByte = SPI.transfer(0b1100100); // 11001_xx_read
          uint8_t   midByte =  SPI.transfer(0b00010000); // 10 00010000 DATAOUT_CTL_REG Register
          uint8_t    lowByte = SPI.transfer(0x00);  // 
          uint8_t    lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    delay(0.2);
    //Serial.println("\n-1 - - -");

    SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
          uint32_t  highByte0 = SPI.transfer(0b1100100); // read
          uint32_t   midByte0 = SPI.transfer(0b00010010); // 12
              lowByte = SPI.transfer(0x00);  // 
              lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    //Serial.println("\n-2 - - -");
    //Serial.print(highByte0,BIN);Serial.println(midByte0,BIN);
    //Serial.print(highByte0,HEX);Serial.print("," );
    //Serial.print(midByte0,HEX);Serial.print(" ; " );
  
    //Serial.println("\n------");
    delay(0.1);
    SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highByte = SPI.transfer(0b11001000); // read
             midByte =  SPI.transfer(0b00010010); // 12
              lowByte = SPI.transfer(0x00);  // 
              lowlowByte = SPI.transfer(0x00);  // 
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    //Serial.println("\n-3 - - -"); 
    //Serial.println(highByte,BIN);
    Serial.print(highByte,HEX);Serial.print("," );
    Serial.print(midByte,HEX);Serial.print(" ; " );

    uint32_t data =  ((uint32_t)highByte << 8 | (uint32_t)midByte) << 2 ;
  
    //Serial.print(data,HEX);Serial.print("  ,  " );Serial.print(data*LSB  /1000000 ,8);Serial.println("V" );
    data = data - 0x20000;
    if (data >=0) {
       Serial.print(data,HEX);Serial.print("  ,  " );Serial.print(data*LSB*2  /1000000 ,4);Serial.println("V" );
    }else if(data < 0){
       Serial.print(data,HEX);Serial.print("  ,  " );Serial.print(-(-1*data*LSB*2  /1000000 ),4);Serial.println("V" );
  }

}

void loop() {
  //read_range();
  read_voltdata();

  delay(3000);
}

 実行例です。入力はArduinoの3.3V端子につないであります。

SPIの転送

 ずっとSPIのライブラリは8ビット単位だと思っていました。最近のArduiono.ccをみると、SPI.transfer16()と複数同時に転送ができるSPI.transfer(バッファ,転送数)が追加されていました。

 SPI.transfer16()の使用例です。スケッチ自体がうまく動いていません。


#include <SPI.h>  
#define CS  9
#define RST 8
const float LSB = 46.875;  // 1.5V x Vref 0010b
//ADS8699
SPISettings settings(1000000, MSBFIRST, SPI_MODE0);

void setup() {
  pinMode(RST, OUTPUT);
  digitalWrite(RST, HIGH);  // reset
  delay(0.1);
  digitalWrite(RST, LOW);
  delay(0.1);
  digitalWrite(RST, HIGH);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  Serial.begin(9600);
  while(!Serial);
  Serial.println("\nADS8699 test");
  SPI.begin();
      Serial.println("\write DATAOUT_CTL_REG Register---- ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
                    // 11010_00_ LS DATAOUT_CTL_REG Register 0x10
            uint16_t  highWord  = SPI.transfer16(0b1101000000010000); 
            uint16_t  lowWord = SPI.transfer16(0x0000); 
        digitalWrite(CS, HIGH);
      SPI.endTransaction();
      delay(0.2);
      Serial.println("\write range ------ ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             // 11010_10_ LS  0x14
            highWord = SPI.transfer16(0b11010100000101000); 
            lowWord = SPI.transfer16(0x0000);  //
        digitalWrite(CS, HIGH);
      SPI.endTransaction();
      delay(0.2);
}

double read_voltdata( ) {
  Serial.println("\nread voltage ------");
  // -1
  Serial.println("-1 - - -");
    SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
            uint16_t highWord = SPI.transfer16(0b1100100000010010); // 11001_xx_read
            uint16_t lowWord = SPI.transfer16(0x0000);
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    Serial.print(highWord,HEX);Serial.print("," );Serial.println(lowWord,HEX);
    delay(0.2);

  // -2
  Serial.println("\n-2 - - -");
  SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highWord = SPI.transfer16(0b1100100000010010); // 11001_xx_read
             lowWord = SPI.transfer16(0x0000);
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    Serial.print(highWord,HEX);Serial.print("," );Serial.println(lowWord,HEX);
    delay(0.2);
    // -3
    Serial.println("\n-3 - - -");
  SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highWord = SPI.transfer16(0b1100100000010010); // 11001_xx_read  12
             lowWord = SPI.transfer16(0x0000);
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    Serial.print(highWord,HEX);Serial.print("," );Serial.println(lowWord,HEX);

    //uint32_t data =  ((uint32_t)highByte << 24 | (uint32_t)midByte << 16  | (highByte0 << 8) & 0b11000000) >> 14;
   // data = data - 0x20000;
    //Serial.print(data,HEX);Serial.print("  ,  " );Serial.print(data*LSB  /1000000 *2, 8);Serial.println("V" );

    // -4
    Serial.println("\n-4 - - -");
    SPI.beginTransaction(settings);
  SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
             highWord = SPI.transfer16(0b1100100000010010); // 11001_xx_read  12
             lowWord = SPI.transfer16(0x0000);
        digitalWrite(CS, HIGH);
    SPI.endTransaction();
    Serial.print(highWord,HEX);Serial.print("," );Serial.println(lowWord,HEX);

    //uint32_t data1 =  ((uint32_t)highByte << 24 | (uint32_t)midByte << 16  | (highByte0 << 8) & 0b11000000) >> 14;
    //data1 = data1 - 0x20000;
    //Serial.print(data1,HEX);Serial.print("  ,  " );Serial.print(data1*LSB  /1000000 *2, 8);Serial.println("V" );

}

void loop() {
  read_voltdata();
  delay(3000);
}

 波形です。下側のクロックを見ると、16ビットがひとまとまりで転送されています。

 SPI.transfer(バッファ,転送数)の使用例です。スケッチ自体がうまく動いていません。


#include "SPI.h"
#define CS  9
#define RST 8
SPISettings settings(1000000, MSBFIRST, SPI_MODE0);
uint32_t* _receive_buffer;
uint32_t* receive_buffer=0;
uint8_t buffer_size = 4;
uint8_t _buffer_size=4;
uint8_t _buffer_store_num=0;
uint8_t _transmit_bytes[4];

//receive_buffer[buffer_size] = {0,0,0,0};
//_receive_buffer = receive_buffer;
//_buffer_size = buffer_size;
  
void setup() {

  
  pinMode(RST, OUTPUT);
  digitalWrite(RST, HIGH);  // reset
  delay(0.1);
  digitalWrite(RST, LOW);
  delay(0.1);
  digitalWrite(RST, HIGH);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  Serial.begin(9600);
  while(!Serial);
  Serial.println("\nADS8699 test");
  SPI.begin();
    Serial.println("\write DATAOUT_CTL_REG Register---- ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
            uint8_t  highByte = SPI.transfer(0b11010000); // 11010_00_ LS DATAOUT_CTL_REG Register
            uint8_t  midByte  = SPI.transfer(0b00100000); // 0x10 _0
            uint8_t  lowByte = SPI.transfer(0x00);  // 
            uint8_t  lowlowByte= SPI.transfer(0b00000000);  // real data
        digitalWrite(CS, HIGH);
      SPI.endTransaction();
        delay(0.2);

  Serial.println("\nwrite range ");
      SPI.beginTransaction(settings);
        digitalWrite(CS, LOW);
            highByte = SPI.transfer(0b11010100); // 11010_10_ LS
            midByte =  SPI.transfer(0b00101000); // 0x14 _0
            lowByte = SPI.transfer(0x00);  // 
            lowlowByte = SPI.transfer(0b00000010);  // 2
        digitalWrite(CS, HIGH);
      SPI.endTransaction();
      delay(0.2);
}

void transmit(uint8_t command, uint16_t address, uint16_t data){
//  Serial.print(_buffer_size,HEX);Serial.print("," );  Serial.print(_buffer_store_num,HEX);;Serial.print("," );
  if(_buffer_size > _buffer_store_num){
    _receive_buffer[_buffer_store_num] = 0;
    _transmit_bytes[0] = (command<<1)|((address>>8)&1);
    _transmit_bytes[1] = (address&0xFF);
    _transmit_bytes[2] = ((data>>8)&0xFF);
    _transmit_bytes[3] = (data&0xFF);
    uint8_t i = 0;
    digitalWrite(CS,LOW);
    SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
    SPI.transfer(_transmit_bytes,4);
    SPI.endTransaction();
    digitalWrite(CS,HIGH);
//Serial.println("\n- - -" );
//      Serial.print(_buffer_size,HEX);Serial.print("," );  Serial.println(_buffer_store_num,HEX);
//Serial.println("- - -" );      
    while(i<4){
      _receive_buffer[_buffer_store_num] = (_receive_buffer[_buffer_store_num]<<8);
      //Serial.print(_receive_buffer[_buffer_store_num],HEX);;Serial.println("," );
      _receive_buffer[_buffer_store_num] |= _transmit_bytes[i];
      //Serial.print(_receive_buffer[_buffer_store_num],HEX);;Serial.print("," );
      i++;
      //Serial.println("\n---" );
    }
    Serial.print(_receive_buffer[_buffer_store_num],HEX);;Serial.print("," );
    
    
    //Serial.print(_receive_buffer[0],HEX);;Serial.print("," );Serial.println(_receive_buffer[1],HEX);
    //Serial.print(_receive_buffer[2],HEX);;Serial.print("," );Serial.println(_receive_buffer[3],HEX);

    //    Serial.print(_receive_buffer[4],HEX);;Serial.print("," );Serial.println(_receive_buffer[5],HEX);
    //Serial.print(_receive_buffer[6],HEX);;Serial.print("," );Serial.println(_receive_buffer[7],HEX);

    _buffer_store_num++;
  }
}

void loop() {
  Serial.println("\n---");
    _buffer_size=4;
 _buffer_store_num=1;
  Serial.println("\nLow");
    //transmit(0b01100000, 0x0010, 0b0000000000000000);
  transmit(0b01100100, 0x0010, 0b0000000000000000);
  _buffer_size=4;
 _buffer_store_num=1;
  Serial.println("\nHigh0");
    //transmit(0b01101010, 0x0010, 0b1111111111111101);
    transmit(0b01100100, 0x0010, 0b0000000000000000);
    transmit(0b01100100, 0x0010, 0b0000000000000000);
    _buffer_size=4;
 _buffer_store_num=1;
  Serial.println("\nHigh");
    transmit(0b01101010, 0x0010, 0b0000000000000000);
    transmit(0b01100100, 0b00101000, 0b0000000000000000);
    transmit(0b01100100, 0b00101000, 0b0000000000000000);
 delay(3000);
}

 実行波形です。8ビット単位ですが、8ビットの単位が密になっているようです。

スケッチ

 電圧を読んで、returnで値を戻すように修正しました。


#include <SPI.h> 
#define CS  9
#define RST 8
uint8_t highByte;
uint8_t midByte;
uint8_t lowByte;
uint8_t lowlowByte;

const float LSB = 46.875;  // 1.5V x Vref 0010b
//ADS8699
SPISettings settings(10000000, MSBFIRST, SPI_MODE0);

void setup() {
  pinMode(RST, OUTPUT);
  digitalWrite(RST, HIGH);  // reset
  delay(0.1);
  digitalWrite(RST, LOW);
  delay(0.1);
  digitalWrite(RST, HIGH);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  Serial.begin(9600);
  while(!Serial);
  Serial.println("\nADS8699 test");
  SPI.begin();
  Serial.println("\nwrite DATAOUT_CTL_REG Register---- ");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b1101000); // 11010_00_ LS DATAOUT_CTL_REG Register
      midByte  = SPI.transfer(0b00010000); // 0x10 _0
      lowByte = SPI.transfer(0x00);  // 
      lowlowByte= SPI.transfer(0b00000000);  // real data
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  delay(0.2);
  Serial.println("\nwrite range ------ ");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b11010100); // 11010_10_ LS
      midByte =  SPI.transfer(0b00101000); // 0x14 _0
      lowByte = SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0b00000010);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  delay(0.2);
}

int read_range(){
  Serial.print("\nread range ------ ");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b11001000); // 11001_xx_ read range1
      midByte =  SPI.transfer(0b00101000); // 14
      lowByte =  SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  delay(0.2);
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b11001000); // 11001_xx_ read range2
      midByte =  SPI.transfer(0b00101000); // 14
      lowByte = SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  Serial.print(highByte,BIN);Serial.println(midByte,BIN);
  Serial.print(highByte,HEX);Serial.print("," );
  Serial.print(midByte,HEX); //Serial.print("," );
  Serial.println("-" );

  //  Serial.print("\nread range 1byte------ ");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b01001000); // 11001_xx_ read range1
      midByte =  SPI.transfer(0b00101000); // 14
      lowByte =  SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  delay(0.2);
  Serial.print("\nread range 1byte------ ");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b01001000); // 11001_xx_ read range1
      midByte =  SPI.transfer(0b00101000); // 14
      lowByte =  SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  Serial.println(highByte,BIN);
  Serial.print(highByte,HEX);Serial.print("," );
  Serial.println(midByte,HEX); //Serial.print("," );
  delay(0.2);
}

double read_voltdata( ) {
  //Serial.println("\nread voltage ------");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b1100100); // 11001_xx_read
      midByte =  SPI.transfer(0b00010000); // 10 00010000 DATAOUT_CTL_REG Register
      lowByte = SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  delay(0.2);
  //Serial.println("\n-1 - - -");
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b1100100); // read
      midByte = SPI.transfer(0b00010010); // 12
      lowByte = SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  delay(0.1);
  SPI.beginTransaction(settings);
    digitalWrite(CS, LOW);
      highByte = SPI.transfer(0b11001000); // read
      midByte =  SPI.transfer(0b00010010); // 12
      lowByte = SPI.transfer(0x00);  // 
      lowlowByte = SPI.transfer(0x00);  // 
    digitalWrite(CS, HIGH);
  SPI.endTransaction();
  //Serial.println("\n-3 - - -"); 
  //Serial.print(highByte,HEX);Serial.print("," );
  //Serial.print(midByte,HEX);Serial.print(" ; " );

  uint32_t data =  ((uint32_t)highByte << 8 | (uint32_t)midByte) << 2 ;

  if (data >=0x20000) {
    data = data - 0x20000;
    //Serial.print(data,HEX);Serial.print("  ,  " );Serial.print(data*LSB*2  /1000000 ,4);Serial.println("V" );
    return data*LSB*2/1000000;
  }else if(data < 0x20000){
    data = data - 0x20000;
    //Serial.print(data,HEX);Serial.print("  ,  " );Serial.print(-(-1* data * LSB * 2  /1000000 ),4);Serial.println("V" );
    return -(-1*data*LSB*2/1000000);
  }
}

void loop() {
  //read_range();
  float A0data = read_voltdata();
  Serial.println(A0data,4);
  delay(3000);
}

前へ

電圧計を作る ② ADS8699のスケッチ その1 レンジの読み書き

次へ

ArduinoでIoTにチャレンジ<その7> Arduino MKR WiFi 1010に接続されたセンサからのデータをWebブラウザに表示する③