raspberry Pi 3に熱電対式の温度計を接続して温度を測定するプログラムです。
熱電対温度計にはMAX31855を使用したK型熱電対アンプモジュールを用いました。
回路図
回路図はFritzingを使い描きました。
プログラム(C言語)
- #include <stdint.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <getopt.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <linux/types.h>
- #include <linux/spi/spidev.h>
- #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
- static void pabort(const char *s)
- {
- perror(s);
- abort();
- }
- static const char *device = "/dev/spidev0.0";
- static uint8_t mode;
- static uint8_t bits = 8;
- static uint32_t speed = 500000;
- static uint16_t delay;
- static void transfer(int fd)
- {
- int ret;
- unsigned tmp = 0;
- double x;
- uint8_t tx[] = {
- 0xFF, 0xFF, 0xFF, 0xFF
- };
- uint8_t rx[ARRAY_SIZE(tx)] = {0, };
- struct spi_ioc_transfer tr = {
- .tx_buf = (unsigned long)tx,
- .rx_buf = (unsigned long)rx,
- .len = ARRAY_SIZE(tx),
- .delay_usecs = delay,
- .speed_hz = speed,
- .bits_per_word = bits,
- };
- ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
- if (ret
- pabort("can't send spi message");
- if(rx[3]&0x01) printf("断線\n");
- if(rx[3]&0x02) printf("GNDにショート\n");
- if(rx[3]&0x04) printf("VCCにショート\n");
- tmp = (rx[2] << 4) | (rx[3] >> 4);
- if(tmp&0x800) {
- tmp = (~tmp + 1) & 0x7FF;
- x = (double)tmp*(-0.0625);
- } else {
- x = (double)tmp * 0.0625;
- }
- printf("現在の室温 %lf\n",x);
- tmp = (rx[0] << 8) | (rx[1]);
- tmp = tmp >> 2;
- if(tmp&0x2000) {
- tmp = (~tmp + 1) & 0x1FFF;
- x = (double)tmp*(-0.25);
- } else {
- x = (double)tmp * 0.25;
- }
- printf("現在の熱電対の温度 %lf\n",x);
- }
- int main(int argc, char *argv[])
- {
- int ret = 0;
- int fd;
- fd = open(device, O_RDWR);
- if (fd < 0)
- pabort("can't open device");
- /*
- * spi mode
- */
- ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
- if (ret == -1)
- pabort("can't set spi mode");
- ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
- if (ret == -1)
- pabort("can't get spi mode");
- /*
- * bits per word
- */
- ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
- if (ret == -1)
- pabort("can't set bits per word");
- ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
- if (ret == -1)
- pabort("can't get bits per word");
- /*
- * max speed hz
- */
- ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
- if (ret == -1)
- pabort("can't set max speed hz");
- ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
- if (ret == -1)
- pabort("can't get max speed hz");
- printf("spi mode: %d\n", mode);
- printf("bits per word: %d\n", bits);
- printf("max speed: %d Hz (%d KHz)\n\n", speed, speed/1000);
- transfer(fd);
- close(fd);
- return ret;
- }
プログラムはSPIのサンプルコードを書き換えたものです。
プログラム(JavaScript)
SPIモジュールをインストールします。
- var SPI = require('pi-spi');
- var spi = SPI.initialize("/dev/spidev0.0"),
- test = Buffer("Hello, World!");
- var msg = Buffer("");
- // reads and writes simultaneously
- spi.read(4,function(e,d) {
- if (e) console.error(e);
- else {
- //--------------------
- var tmp,x;
- if(d[3]&0x01) console.log("断線\n");
- if(d[3]&0x02) console.log("GNDにショート\n");
- if(d[3]&0x04) console.log("VCCにショート\n");
- tmp = (d[2] << 4) | (d[3] >> 4);
- if( (tmp&0x800) != 0 ) {
- tmp = (~tmp + 1) & 0x7FF;
- x = tmp*(-0.0625);
- } else {
- x = tmp * 0.0625;
- }
- console.log("現在の室温 "+ x);
- tmp = (d[0] << 8) | (d[1]);
- tmp = tmp >> 2;
- if((tmp&0x2000) != 0 ) {
- tmp = (~tmp + 1) & 0x1FFF;
- x = tmp*(-0.25);
- } else {
- x = tmp * 0.25;
- }
- console.log("現在の熱電対の温度 "+ x);
- //--------------------
- }
- });