初めてのRaspberry Pi Pico ㉔ C言語 16ビットADC ADS1110

　Picoには12ビット4チャネルのA-Dコンバータが内蔵されています。ENOB（effective number of bits：有効ビット数）が9.5なので、もう少し高いビット数がほしいという想定で外部にICを追加します。


###ADS1110のおもなスペック

- ビット数　16
- チャネル数　1
- 基準電圧　2.048V ±0.05%、ドリフト5ppm/℃
- 電源電圧　2.7～5.5V
- 消費電流　240µA
- 入力　差動、シングルエンド
- 変換方式　ΔΣ型
- データ・レート　15SPS（16ビット）
- インターフェース　I2C
- I2C転送速度　最大3.4MHz
- スレーブ・アドレス　発注時に指定できる。表面にED0の印字は0x48
- プログラマブル・ゲイン・アンプ　1/2/4/8倍が設定できる

###接続

　ボード化されたADS1110は、ebayで購入しました（購入時400円）。Digi-KeyでICは約500円です。


<img width="220" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/862bfa0f-604c-3db2-2790-2222f9503282.png">



|ADS1110ボードの端子|	Picoの端子(GPIO)	|名称|
|------------|------------|:-------------:|:------|
|Vin＋|	-|	-|
|Vin-|	-|	-|
|Vcc|	3.3V|	3.3V|
|GND|	GND|GND|
|SCL|	GP9|	SCL|
|SDA|	GP8|	SDA|


　プルアップ抵抗10kΩがSDA/SCLに入っていました。
　ADS1110の入力には、直流標準電圧電流発生器TR6142で電圧を入力しています。1.0000だと小数点第4位まで正確です。

###プログラムads1110.c
　フォルダ名はads1110としました。CMakeLists.txtは省略します。17回以前を参考にしてください。

 　　[ADS1110データシート](https://www.tij.co.jp/jp/lit/ds/symlink/ads1110.pdf?ts=1613970087714&ref_url=https%253A%252F%252Fwww.tij.co.jp%252Fproduct%252Fjp%252FADS1110)

　設定用レジスタのアドレスはありません。

　◆設定レジスタ　デフォルト b10001100

|b7|b6|b5|b4|b3|b2|b1|b0|
|-------|-------|-------|-------|-------|-------|-------|-------|
|ST/DRDY|0|0|SC|DR1|DR0|PGA1|PGA0| 

``SC=0は連続変換、'1'は1回のみの変換。
DR1,DR0はサンプリング・レート。デフォルト15SPSで16ビット。
PGA1,PGA0はアンプの増幅度。'00'=×1、'01'=×2、'10'=×4、'11'=×8。``

　設定時に書き込むデータは、PGAによって変化します。PGAに倍率nを設定したら、読み取った電圧をnで割ります。
　x1の**入力電圧**はVrefなので約2.5V、x2のときはVrefの半分、x4のときはVrefの1/4、x8x4のときはVrefの1/8になります。増幅度を上げると分解能は向上しますが、許容入力電圧が下がります。

　読み出すレジスタのアドレスはありません。
　読み出したデータは2バイトで、0から32767までのデータです。2の補数形式で、D15は符号を表します。
　　``D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0``

　内部の基準電源電圧は2.48Vですが、1.0000V入力に対して少し低めに出ていたので、2.028とわずかに変更しました。
　I2Cの転送速度はPicoの上限1MHzにしました。


```cpp
/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

#define I2C_PORT  i2c0
static int addr = 0x48;
static float Vref = 2.028;

void setup_I2C(){
    // This example will use I2C0 on GPIO8 (SDA) and GPIO9 (SCL) running at 1MHz.
    i2c_init(I2C_PORT, 1000 * 1000);
    gpio_set_function(8, GPIO_FUNC_I2C);
    gpio_set_function(9, GPIO_FUNC_I2C);
    gpio_pull_up(8);
    gpio_pull_up(9);
}

float readADC(uint8_t PGAgain){
    printf(" SamplingRate is 15 <-16bit\n");
    uint8_t val = 0b10001100;
    switch (PGAgain) {
        case 1: val = val | 0x00; break;
        case 2: val = val | 0x01; break;
        case 4: val = val | 0x02; break;
        case 8: val = val | 0x03; break;
        default:
        printf("PGA 1 2 4 8");
    }
    i2c_write_blocking(I2C_PORT, addr, &val, 1, true);

    uint8_t buffer[2];
    i2c_read_blocking(I2C_PORT, addr, buffer, 2, false);
    uint16_t temp = (buffer[0]<<8) | buffer[1];
    int16_t tempSign = -(temp & 0b1000000000000000) | (temp & 0b0111111111111111);
    float V = Vref * tempSign / 32767;
    return V / PGAgain;
}

int main() {
    stdio_init_all();
    printf("\nstart ADS1110\n");
    setup_I2C();

    printf("input: %.5fV\n", readADC(2));

    return 0;
}

```

　PGA=1のときの実行結果です。入力電圧=1.0000V、Reset、入力電圧=-1.0000V、Resetと4回実行しています。

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c99ec682-d22e-f2fe-76b0-d8b7290350e2.png">

　PGA=2のときの実行結果です。入力電圧=1.0000V、Reset、入力電圧=-1.0000V、Resetと4回実行しています。
　最初の実行時に1/2になりました。バグが残っているようです。
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/48b4ccc4-f2ba-dce2-b9fe-06406e1633b3.png">