Arduino I2C LCD2004 HelloWorld

はじめに

20桁×4行のLCD LCD2004をArduinoで制御してHelloWorldしました。 検索するとよくヒットするLiquidCrystal_I2C.hを使用するタイプです。

使ったもの

  • LCD2004
  • I2Cアダプタ(PCF8574T)
  • Arduino UNO R2

LCD2004

アリエクで以下のLCDを1500円程度で購入しました。I2Cアダプタ付きです。 ビッグサイズを謳っており、iPhone12miniと同じくらいのサイズです。

https://ja.aliexpress.com/item/1005007298503814.html?spm=a2g0o.order_list.order_list_main.32.7937585arihGIF&gatewayAdapt=glo2jpn#nav-review

LCDの制御ICは商品説明に

hd44780,st7066,eqvチップ

とあるので、日立のHD44780の互換ICが載っていると思われます。

I2CアダプタとLCDははんだ付けされておらず、別々で届きました。

LCDは18pinで以下のピンアサインになっています。

I2Cアダプタは16pinなので、pin1から合わせて、pin17,18がNCとなります。

I2Cアダプタ基板の表面しかパターンを追えてませんが、おそらく回路は以下サイトさんと同じと思われます。

qiita.com

DB0~DB3は未接続で、DB4~DB7は繋がっているため4bitモードだと思われます。

I2Cアダプタ(PCF8574T)

PCF8574TはI2C接続のI/Oエキスパンダです。

青いポテンショメーター下のA0,A1,A2の空きランドでI2Cのスレーブアドレスを決定しますが、デフォルトでは3つとも開放なのでアドレスは0x27となります。

PCF8574Tのデータシート(https://www.nxp.jp/docs/en/data-sheet/PCF8574_PCF8574A.pdf)の7.1.1 Address mapsをみるとI2Cアドレス(A0~6の7bit)のA0,A1,A2がHIGH(開放でVDDとなりHIGH)となり、7-bit hexadecimal address without R/Wが27h(=0x27)となることがわかります。A3~6のbitは固定です。

Arduino IDEのスケッチ例-Wire-i2c_scanner.inoを使用して、アドレスが0x27であることが確認できました。

他のデバイス(STM32など)はアドレスはR/Wも含めた8bitで送信しますが、ArduinoはR/Wを含めず7bitです。Wire.hがそのようになっています。(LiquidCrystal_I2C.hではWire.hを使用しています)

また、I2Cは信号線のプルアップが必要ですが、Wire.hでは内部プルアップしてくれるので外付け抵抗が不要です。 なので、ただ線をつなぐだけでOKです。

接続

ArduinoとI2Cアダプタを4本接続するだけです。

Arduino I2Cアダプタ
A4 SDA
A5 SCL
5V VCC
GND GND

プログラム

色々書きましたが、LiquidCrystal_I2C.hを使う場合は細かいことは意識することなく表示することができます。(LiquidCrystal_I2C.hがいい感じにやってくれます)

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4); // スレーブアドレス0x27 20桁4行

void setup() {
  lcd.init(); 
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("0 Hello, world!");
  lcd.setCursor(0, 1);
  lcd.print("1 Hello, world!");
  lcd.setCursor(0, 2);
  lcd.print("2 Hello, world!");
  lcd.setCursor(0, 3);
  lcd.print("3 Hello, world!");

}

void loop(){
  lcd.setCursor(0, 0);
  lcd.print("0 Hello, world!");
  delay(1000);
  lcd.setCursor(0, 0);
  lcd.print("1 world, world!");
  delay(1000);
}

ハマったところ

コントラスト調整しておらず表示が出ない。

表示が出ないと思ったら、コントラストが悪く出ていませんでした。I2Cアダプタのポテンショメーターで調整します。

参考

参考にさせていただき、ありがとうございました。

iot.keicode.com

docs.sunfounder.com

qiita.com

ch32v003fun CH32V003F4P6 シリアル通信

はじめに

シリアル通信を試しました

注意点

SWIOだけではシリアル通信できません。

WCH-LinkEのRXとCH32V003F4P6のUTX(pin2,PD5)を接続する必要があります。

接続

3.3V GND SWIO(PD1) TX(PD5)の4本です。

プログラム

サンプルがほぼそのままで動作しました。楽〜

C:\Users\USERNAME\Downloads\ch32v003fun\examples\uart_tx_dma\uart_tx_dma.c

以下記事でch32v003funをダウンロードした場所と同じです。

atooshi-note.hatenablog.jp

接続してポートを認識しており(COM7でした)、teratermで通信を確認しました。

/*
 * This example uses DMA for the UART to transfer the "Hello World!\r\n" string
 * once per second. Connect a UART Rx pin to D5, flash the example, setup your
 * uart for 115200n1 and the messages should appear

 シリアル通信のチェック
 */

#include "ch32v003fun.h"

// Set UART baud rate here
#define UART_BR 115200
// LED on D6 (nanoCH32V003 board)
// #define LED_PIN 6
#define LED_PIN 4 // ch32v003f4p6のdevelopmetboard

// DMA transfer completion interrupt. It will fire when the DMA transfer is
// complete. We use it just to blink the LED
__attribute__((interrupt)) __attribute__((section(".srodata")))
void DMA1_Channel4_IRQHandler(void)
{
    // Clear flag
    DMA1->INTFCR |= DMA_CTCIF4;

    // Blink LED
    GPIOD->OUTDR ^= 1<<LED_PIN;
}

static void led_setup(void)
{
    RCC->APB2PCENR = RCC_APB2Periph_GPIOD;
    GPIOD->CFGLR =
        ((GPIO_CNF_IN_PUPD)<<(4*1)) | // Keep SWIO enabled.
        (GPIO_Speed_2MHz | GPIO_CNF_OUT_PP)<<(4*LED_PIN);

    // LED ON
    GPIOD->BSHR = 1<<LED_PIN;
}

static void uart_setup(void)
{
    // Enable UART and GPIOD
    RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1;

    // Push-Pull, 10MHz Output on D5, with AutoFunction
    GPIOD->CFGLR = (GPIOD->CFGLR & ~(0xF<<(4*5))) |
            ((GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*5));

    // Setup UART for Tx 8n1
    USART1->CTLR1 = USART_WordLength_8b | USART_Parity_No | USART_Mode_Tx;
    USART1->CTLR2 = USART_StopBits_1;
    // Enable Tx DMA event
    USART1->CTLR3 = USART_DMAReq_Tx;

    // Set baud rate and enable UART
    USART1->BRR = ((FUNCONF_SYSTEM_CORE_CLOCK) + (UART_BR)/2) / (UART_BR);
    USART1->CTLR1 |= CTLR1_UE_Set;
}

static void dma_uart_setup(void)
{
    // Enable DMA peripheral
    RCC->AHBPCENR = RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1;

    // Disable channel just in case there is a transfer in progress
    DMA1_Channel4->CFGR &= ~DMA_CFGR1_EN;

    // USART1 TX uses DMA channel 4
    DMA1_Channel4->PADDR = (uint32_t)&USART1->DATAR;
    // MEM2MEM: 0 (memory to peripheral)
    // PL: 0 (low priority since UART is a relatively slow peripheral)
    // MSIZE/PSIZE: 0 (8-bit)
    // MINC: 1 (increase memory address)
    // CIRC: 0 (one shot)
    // DIR: 1 (read from memory)
    // TEIE: 0 (no tx error interrupt)
    // HTIE: 0 (no half tx interrupt)
    // TCIE: 1 (transmission complete interrupt enable)
    // EN: 0 (do not enable DMA yet)
    DMA1_Channel4->CFGR = DMA_CFGR1_MINC | DMA_CFGR1_DIR | DMA_CFGR1_TCIE;

    // Enable channel 4 interrupts
    NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}

static void dma_uart_tx(const void *data, uint32_t len)
{
    // Disable DMA channel (just in case a transfer is pending)
    DMA1_Channel4->CFGR &= ~DMA_CFGR1_EN;
    // Set transfer length and source address
    DMA1_Channel4->CNTR = len;
    DMA1_Channel4->MADDR = (uint32_t)data;
    // Enable DMA channel to start the transfer
    DMA1_Channel4->CFGR |= DMA_CFGR1_EN;
}

int main(void)
{
    static const char message[] = "Hello World!!!\r\n";

    SystemInit();
    led_setup();
    uart_setup();
    dma_uart_setup();

    while (1)
    {
        dma_uart_tx(message, sizeof(message) - 1);
        Delay_Ms(1000);
    }
}

参考

http://dj-higo.cocolog-nifty.com/blog/2023/09/post-677c29.html

ソリオMA15S ELM327 複数PID同時問い合わせ

はじめに

ELM327は複数PIDを同時に扱うことができ、時短になります。

車両が対応していれば、最大6byte(6個)のpidを同時に問い合わせ可能です。

ソリオは対応してる様です。

返答データが6byte以上だと、ELM327 データシートのMultiline Responses (p44/82)に記載があるように複数行で返ってきます。

使用したもの

ELM327 v1.5

結果

PIDを一つずつ増やしていき、挙動を確認しました。

PID 1byte(1種類)(通常)

> 0105
41 05 7A
  • 送信 : 0x05 (Engine coolant temperature)
  • 回答 : 0x7A
    • 0x7A = 0d122
  • 値 : 122 - 40 = 82℃

PID 2byte(2種類)

> 01050c
41 05 7A 0C 0A 16

順番は service(01) PID1(05) PID1のdata(7A) PID2(0C) PID2のdata1(0A) PID2のdata2(16)

  • PID1 : 0x05
  • PID2
  • 送信 : 0x0c (Engine speed)
  • 回答 : 0x0A16
    • 0x0A = 0d10
    • 0x16 = 0d22
  • 値 : (256 * 10 + 22) / 4 = 645rpm

PID 3byte(3種類)

> 01050c0d
008
0: 41 05 7A 0C 0B AE
1: 0D 00 00 00 00 00 00

回答が2行になります

0x008 = 0d8 → データ数8byte(8個)

0Dの回答の00までで8個です

その先は13個まで00で埋まっています

(ELM327のMultiline Responsesを参照)

  • PID1 0x05
  • PID2 0x0c
  • PID3
  • 送信 : 0x0d (Vehicle speed)
  • 回答 : 0x00
  • 値 : 0km/h

PID 4byte(4種類)

> 01050c0d0f
00A
0: 41 05 7A 0C 0A 06
1: 0D 00 0F 4A 00 00 00
  • 0x00A = 0d10 → データ数10byte
  • PID1 0x05
  • PID2 0x0c
  • PID3 0x0d
  • PID4
  • 送信 : 0x0f (Intake air temperature)
  • 回答 : 0x4A
  • 値 : 74 - 40 = 34℃

PID 5byte(5種類)

> 01050c0d0f1f
00D
0: 41 05 7A 0C 0B B0
1: 0D 00 0F 4B 1F 0A AB
  • 0x00D = 0d13 → データ数13byte
  • PID1 0x05
  • PID2 0x0c
  • PID3 0x0d
  • PID4 0x0f
  • PID5
  • 送信 : 0x1f (Run time since engine start)
  • 回答 : 0x0AAB
    • 0x0A = 0d10
    • 0xAB = 0d171
  • 値 : 256 * 10 + 171 = 2731

PID 6byte(6種類)

> 01050c0d0f1f11
00F
0: 41 05 7A 0C 0A 1C
1: 0D 00 0F 4B 1F 0A B2
2: 11 22 00 00 00 00 00
  • 0x00F = 0d15 → データ数15byte
  • PID1 0x05
  • PID2 0x0c
  • PID3 0x0d
  • PID4 0x0f
  • PID5 0x1f
  • PID6
  • 送信 : 0x11 (Throttle position)
  • 回答 : 0x22
  • 0x22 = 0d34
  • 値 : (100 / 255 ) * 34 = 13.3%

PID 7byte(7種類)

> 01050c0d0f1f1142
?

ハテナになる

  • PID1 0x05
  • PID2 0x0c
  • PID3 0x0d
  • PID4 0x0f
  • PID5 0x1f
  • PID6 0x11
  • PID7
  • 送信 : 0x42

参考

minkara.carview.co.jp

ch32v003funをWindowsに構築しCH32V003F4P6でLチカ

はじめに

ch32v003funの環境をWindowsに構築したメモです。

Wikiの通り(以下↓)にやれば良いのですが、自分のまとめをしました。

github.com

環境

  • Windows10
  • CH32V003F4P6 Development board
  • WCH-LinkE version 2.15

Development boardの詳細は以下↓

atooshi-note.hatenablog.jp

構築

githubからch32v003funを好きなフォルダにダウンロードします。

github.com

私は、C:\Users\USERNAME\Downloads\ch32v003funにgit cloneしました。

gccインストール

以下から、risc-v-gcc10.1.0.exe (22 MB) をダウンロード、イントールします。

gnutoolchains.com

インストール先:C:\SysGCC

The minichlink.exe file is already ready to go in the minichlink folder.

とあるように、minichlink.exeはmakeしなくてもすでに入っています。

Zading

以下より、Zadingをダウンロードします。

zadig.akeo.ie

zadig-2.9.exeをダウンロードしました。

Zadingでドライバをインストールする前はWCH-LinkEはInterfaceで認識しています。

ZadingでWinUSB(?)をインストールします。

インストール後はUSBデバイスとして認識するようになります。

Lチカ

サンプルプログラムを作ってみます。

以下を参考にさせていただきました。

74th.hateblo.jp

C:\Users\USERNAME\Downloads\ch32v003fun\examples\template をコピーし、

C:\Users\USERNAME\Downloads\ch32v003fun\examples\blinktest20241221 を作りました。

template.c、template.h のファイル名を作りたいプログラム名(例えば usb_rebooter.c)に変更します。

とありますが、template.hは無く、funconfig.hだったので、名前変更はtemplate.cの方だけにしました。

blinktest20241221.c に変更しています。

CH32V003F4P6 Development BoardのD1が点滅するプログラムです。

サンプルプログラム(C:\Users\USERNAME\Downloads\ch32v003fun\examples\blink\blink.c)をコピペして不要部分をコメントアウトしたので、不要行が多いです。

/*
blinktest20241221
D1のblink
*/

#include "ch32v003fun.h"
#include <stdio.h>

// use defines to make more meaningful names for our GPIO pins
//#define PIN_1 PD0
#define PIN_K PD4
//#define PIN_BOB PD6
//#define PIN_KEVIN PC0

int main()
{
    SystemInit();

    // Enable GPIOs
    funGpioInitAll();
    
    //funPinMode( PIN_1,     GPIO_Speed_10MHz | GPIO_CNF_OUT_PP );
    funPinMode( PIN_K,     GPIO_Speed_10MHz | GPIO_CNF_OUT_PP );
    //funPinMode( PIN_BOB,   GPIO_Speed_10MHz | GPIO_CNF_OUT_PP );
    //funPinMode( PIN_KEVIN, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP );

    while(1)
    {
        //funDigitalWrite( PIN_1,     FUN_HIGH );
        funDigitalWrite( PIN_K,     FUN_HIGH );
        //funDigitalWrite( PIN_BOB,   FUN_HIGH );
        //funDigitalWrite( PIN_KEVIN, FUN_HIGH );
        Delay_Ms( 100 );
        //funDigitalWrite( PIN_1,     FUN_LOW );
        funDigitalWrite( PIN_K,     FUN_LOW );
        //funDigitalWrite( PIN_BOB,   FUN_LOW );
        //funDigitalWrite( PIN_KEVIN, FUN_LOW );
        Delay_Ms( 250 );
    }
}

なお、コードの作成を ch32v003fun の examples ディレクトリ内に新しくディレクトリを作って行った場合、TARGET だけを書き換えれば良いです。

とのことですので、Makefileは

TARGET:=blinktest20241221

とだけにしました。

接続

3.3V, GND, SWIO(pin18, PD1)の3本を接続するだけです。

PD1はJ2 7pin

もしくは、U4 2pin です。

どちらでも良いです。

make、書き込み

このディレクトリにpowershellで移動してmakeします。

makeが入っていない場合は入れる必要があります。

私はmakeは元々入れてありました。

PS C:\Users\USERNAME> make -v
GNU Make 3.82
Built for i686-pc-mingw32
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

makeが通り、WCH-LinkEを認識、CH32V003F4P6を検出して書き込みまで完了しています。

PS C:\Users\USERNAME\Downloads\ch32v003fun\examples\blinktest20241221> make
riscv64-unknown-elf-gcc -E -P -x c -DTARGET_MCU=CH32V003 -DMCU_PACKAGE= -DTARGET_MCU_LD=0 -DTARGET_MCU_MEMORY_SPLIT= ../../ch32v003fun/ch32v003fun.ld > ../../ch32v003fun/generated_ch32v003.ld
riscv64-unknown-elf-gcc -o blinktest20241221.elf ../../ch32v003fun/ch32v003fun.c blinktest20241221.c   -g -Os -flto -ffunction-sections -fdata-sections -fmessage-length=0 -msmall-data-limit=8 -march=rv32ec -mabi=ilp32e -DCH32V003=1 -static-libgcc -I/usr/include/newlib -I../../ch32v003fun/../extralibs -I../../ch32v003fun -nostdlib -I. -Wall  -Wl,--print-memory-usage -Wl,-Map=blinktest20241221.map -L../../ch32v003fun/../misc -lgcc -T ../../ch32v003fun/generated_ch32v003.ld -Wl,--gc-sections
Memory region         Used Size  Region Size  %age Used
           FLASH:        1844 B        16 KB     11.25%
             RAM:          0 GB         2 KB      0.00%
riscv64-unknown-elf-objdump -S blinktest20241221.elf > blinktest20241221.lst
riscv64-unknown-elf-objcopy -O binary blinktest20241221.elf blinktest20241221.bin
riscv64-unknown-elf-objcopy -O ihex blinktest20241221.elf blinktest20241221.hex
make -C ../../ch32v003fun/../minichlink all
make[1]: Entering directory `C:/Users/USERNAME/Downloads/ch32v003fun/minichlink'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `C:/Users/USERNAME/Downloads/ch32v003fun/minichlink'
../../ch32v003fun/../minichlink/minichlink -w blinktest20241221.bin flash -b
Found WCH Link
WCH Programmer is CH32V307 version 2.15
Full Chip Type Reply: [8] 82-0d-05-09-00-30-05-00-03
Detected: CH32V003
Setup success
Flash Storage: 16 kB
Part UUID    : f7-36-ab-cd-5f-54-bc-51
PFlags       : ff-ff-ff-ff
Part Type (B): 00-30-05-00
Read protection: disabled
Interface Setup
Writing image

Image written.

まとめ

書き込み手順をまとめると、

  1. powershellでプログラムがあるフォルダに移動
  2. WCH-LinkEとマイコンを接続して通電
  3. powershellでmakeと打ち、enter

これで書き込まれます。簡単~

その他

ZadingでWinUSBをインストールした後は、Arduinoで書き込みができなくなります。

再度Zadingで戻せば戻るかもしれません(未確認です)

WCH-LinkEは安いので、戻さずに複数本持っていても良いかもしれません。

以上:)

アリエクで買ったCH32V003F4P6 Development board

はじめに

アリエクで買ったCH32V003F4P6 Development boardのメモです。 適当に買ってあったのですが、使う時に回路図がわからず調べました。

WCH-LinkEとDevelopment boardのセットで1000円ほどで買いました。以下です。

https://ja.aliexpress.com/item/1005005834050641.html

Development board単体なら300円くらいです。やすっ。

商品ページには回路図が載っていないのですが、一番下にドキュメントの記載がありました。

ドキュメント

http://wiki.icbbuy.com

回路図

回路図は以下です。

wiki.icbbuy.com

LEDが2つ載ってますが、一つは電源投入で点灯するLED(PWR)です。

もう一つはLチカ確認用(D1)なのですが、PD4に接続されています。

以上:)

ソリオMA15Sが対応しているPIDを調べる

はじめに

OBDから取れるデータは何か、対応しているPIDを調べてみました。

Wikiに載ってるStandard PIDsは全て対応しているわけでは無いため、ソリオが対応しているPIDを調べてみます。

使ったもの

  • ELM327 v1.5

調べ方

en.m.wikipedia.org

上記wikiにあるように、ELM327からコマンド01 00(service 01 PID 00)を送信するとPID 01からPID 20までで、対応しているPIDのビットには1、未対応のPIDのビットには0がセットされます。

wikiの例だと、01 00の応答が0x BE 1F A8 13だった場合、これを2進数に変換すると 0b 1011 1110 0001 1111 1010 1000 0001 0011 となるため 対応してるPIDは1が立っているPID 01, 03, 04, 05, 06, 07, 0C, 0D, 0E, 0F, 10, 11, 13, 15, 1C, 1F ,20となります。

左端から見ていくため、例えば左端の0xB=0b1011では、PID 01は対応、02は未対応、03,04は対応ということになります。

PID 20が対応しているということは次の PIDs supported [$21 - $40] ということになるため、PID 21 から PID 40 が存在するということになります。

コマンド01 00と同様に考えて、01 20を送信するとPID 21 から PID 40 までの対応状況が分かります。

対応状況

では、ソリオがどうかと言いますと、以下の結果となりました。

0100
> 7E8 06 41 00 BE 3F A8 03

0120
> 7E8 06 41 20 80 05 B0 01

0140
> 7E8 06 41 40 6A D0 00 00

0160
> NO DATA

0180
> NO DATA

01A0
> NO DATA

データは下4byteなので2進数に変換し、対応しているPIDを記載します。

  • コマンド 0100
  • 応答(hex) BE 3F A8 03
  • 応答(bin) 1011 1110 0011 1111 1010 1000 0000 0011
  • → PID 01, 03, 04, 05, 06, 07, 0B, 0C, 0D, 0E, 0F, 10, 11, 13, 15, 1F, 20

  • 0120

  • 80 05 B0 01
  • 1000 0000 0000 0101 1011 0000 0000 0001
  • → PID 21, 2E, 30, 31, 33, 34, 40

  • 0140

  • 6A D0 00 00
  • 0110 1010 1101 0000 0000 0000 0000 0000
  • → PID 42, 43, 45, 47, 49, 4A, 4C

0140の応答の右端bitが0なので、それ以降は対応しているPIDはありません。

実際0160の回答はNO DATAになっています。

まとめ

まとめると、以下になります。

PID(hex) Description bytes Formula
01 Monitor status since DTCs cleared 4
03 Fuel system status 2
04 Calculated engine load 1
05 Engine coolant temperature 1 A - 40
06 Short term fuel trim (STFT)—Bank 1 1
07 Long term fuel trim (LTFT)—Bank 1 1
0B Intake manifold absolute pressure 1
0C Engine speed 2 (256 * A + B) / 4
0D Vehicle speed 1 A
0E Timing advance 1
0F Intake air temperature 1 A - 40
10 Mass air flow sensor (MAF) air flow rate 2
11 Throttle position 1 (100 / 255) * A
13 Oxygen sensors present (in 2 banks) 1
15 Oxygen Sensor 2 2
1F Run time since engine start 2 256 * A + B
21 Distance traveled with malfunction indicator lamp (MIL) on 2 256 * A + B
2E Commanded evaporative purge 1
30 Warm-ups since codes cleared 1
31 Distance traveled since codes cleared 2 256 * A + B
33 Absolute Barometric Pressure 1
34 Oxygen Sensor 1 4
42 Control module voltage 2 (256 * A + B) / 1000
43 Absolute load value 2
45 Relative throttle position 1
47 Absolute throttle position B 1
49 Accelerator pedal position D 1
4A Accelerator pedal position E 1
4C Commanded throttle actuator 1

数式のA,B,Cについて

In the formula column, letters A, B, C, etc. represent the first, second, third, etc. byte of the data. For example, for two data bytes 0F 19, A = 0F and B = 19. Where a (?) appears, contradictory or incomplete information was available

おわり:)

ArduinoでOBDをシミュレートしてELM327とつなぐ

はじめに

車両のOBDでデータを取りたいと思っていますが、車両で開発は大変なのでArduinoで車両をシミュレートする環境を作りました。

参考

以下を参考にさせていただきました。ありがとうございます。

qiita.com

環境

  • windows
  • Arduino nano互換機
  • MCP_CAN_lib v1.5.1
  • ELM327 v2.1
  • MCP2515モジュール
  • Car Scanner(Androidアプリ)
  • OBDケーブル

Arduino nano互換機 について

久々に使ったので、最初書き込みができなくて困りました。

IDEでOld Bootloaderを選択します。

MCP2515モジュール について

Amazonで3個セット安いやつです。

不良が混じっていることが多いみたいなのでモジュールを2つ使って動作確認をしました。

こちらは以下を参考にして動作確認をしました。ありがとうございます。

qiita.com

OBDケーブル について

以下を使用しました。

レビューには商品袋に記載のピンアサインと実際のピンアサインは違うとあったのでテスターチェックしましたが、商品袋に記載の通りでした。なのでGreen - CAN-H,Green/White - CAN-Lで接続しています。

Pin Color Function
4 Orange Chassis GND
5 Light blue Signal GND
6 Green CAN high
14 Green/white CAN low
16 Red 12V

変更点

参考のそのままでは動かなかったので、以下を変更しています。(参考での変更も含みます)

また、参考ではArduino Unoですが、私はnanoなのでnanoに合わせて接続しています。

Pin Function
D10 SS
D11 Mosi
D12 Miso
D13 sck

OBD_Sim.inoにて

  • CSピンを9ピン→10ピンに変更
// MCP_CAN CAN0(9);                                // Set CAN0 CS to pin 9
MCP_CAN CAN0(10);                                // Set CAN0 CS to pin 10
  • 20MHz→8MHzに変更
// if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_20MHZ) == CAN_OK)
if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
  • OBDの5pin(Signal GND)は未接続

    • CANは差動信号なのでGNDは不要と考え繋ぎませんでした。動作しています。
  • MCP2515モジュールのintとArduinoのpin2をつなぐ(割り込み)

    • 参考では未接続ですが、動きませんでした。プログラムをみるとmainloopでintピンを見て割り込み待ちしていたので接続したところ動作しました。

その他

Car Scannerでプロトコルは自動認識されるため以下は1or0のどちらでも良いです。

  • 1ならISO 15765-4 CAN(11bit ID 500kbaud)
  • 0ならISO 15765-4 CAN(29bit ID 500kbaud)
#define standard 0