前回、Digispark(ATTiny85) をI2CのSlaveで使用(TinyWireS)して、RaspberryPi(Master)と通信してみる の続きで、
#ラズパイにADCがない! => 手元にあるATTiny85のADCの値をI2Cで受け渡せば... ってのが動機。
を解消。フォトセルを使って、電圧を適当にかえて、A/D変換して、値をとる。
準備
- 前回と同様の環境
ピン配
- Digisparkの
P4
をADCポートとして使用。 - 接続は
- 5V - フォトセル - P4 - 1Kオームの抵抗 - GND
- フォトセル と 1Kオームの抵抗 のあいだにDigispark::P4端子を接続
- 5Vがリファレンスなので、0V=0, / 5V=1023くらいの値がかえってくるハズ。
- あとは前回と同じ。P0=I2C-SDA, P2=I2C-CLK
Digispark側のコード
- get_adcVal()という、P4の電圧値を読みとって、i2c_regs[0]と[1]に格納する関数追加。loop内で呼び続ける。
- あとは、前回とほぼ同じ。
#define I2C_SLAVE_ADDRESS 0x5A // the 7-bit address
#define LED_PIN 1 // DigiSpark LED pin
#include "TinyWireS.h"
#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 16 )
#endif
volatile uint8_t i2c_regs[] =
{
0xDE,
0xAD,
0xBE,
0xEF,
};
int get_adcVal() {
analogReference(DEFAULT); // Reference = 5V
int adcValue = analogRead(2); // Read P4
i2c_regs[0] = adcValue & 0xff;
i2c_regs[1] = (adcValue>>8) & 0xff;
}
volatile byte reg_position;
const byte reg_size = sizeof(i2c_regs);
void requestEvent()
{
reg_position %= reg_size;
TinyWireS.send(i2c_regs[reg_position]);
reg_position++;
}
void receiveEvent(uint8_t howMany)
{
// Sanity check
if ((howMany < 1) || (howMany > TWI_RX_BUFFER_SIZE)) return;
reg_position = TinyWireS.receive();
howMany--;
while(howMany--)
{
reg_position %= reg_size;
i2c_regs[reg_position] = TinyWireS.receive();
reg_position++;
}
}
void setup(){
pinMode(4, INPUT); // P4=ADC Input
pinMode(LED_PIN,OUTPUT);
mt08Blink(LED_PIN, 2); //開始時LED点滅
TinyWireS.begin(I2C_SLAVE_ADDRESS);
TinyWireS.onReceive(receiveEvent);
TinyWireS.onRequest(requestEvent);
}
void loop()
{
TinyWireS_stop_check();
get_adcVal();
}
void mt08Blink(byte led, byte times)
{
times *= 2;
while(times > 0) {
digitalWrite(led,(times & 0x01) ? LOW : HIGH);
delay (200);
times--;
}
}
実行例
pi@raspberrypi ~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- 5a -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi ~ $ i2cget -y 1 0x5a 0x00; i2cget -y 1 0x5a 0x01
0xed
0x02
pi@raspberrypi ~ $ i2cget -y 1 0x5a 0x00; i2cget -y 1 0x5a 0x01
0x59
0x00
ADC(16進) | ADC(10進) | ADC電圧 | 電圧実測(テスタで計測) |
---|---|---|---|
0x02ED | 749 | 5V * 749/1024 = 3.66V | 3.64V |
0x0059 | 89 | 5V * 89/1024 = 0.43V | 0.412V |
予定は未定
- 一定間隔で値を読み出して、クらウドとかにデータ送って、グラフなんかつくったりしちゃうとかっこいいよね。