ELM327とArduinoとLCD2004でOBDデータ表示

はじめに ELM327とArduinoとLCD2004で車両情報を表示してみました。 ELM327ではTrqueやCar Scannerなどのアプリで色々な車両情報は見れますが、だいたい見る項目は決まってきましたので作ってみました。 アプリより表示のレスポンスが向上しました。 「Arduino ELM327」などでググると、以下のELMduinoのような便利なライブラリも見つかりましたが、今回は使っていません。 PowerBroker2/ELMduino: Arduino OBD-II Bluetooth Scanner Interface Library for Car Hacking Projects 使ったもの ELM327 v1.5 Arduino UNO R2 Arduino Pro mini互換品 ATMega328,16MHz,5V LCD2004とI2Cアダプタ こちらと同じもの → Arduino I2C LCD2004 HelloWorld | atooshi-note ELM327殻割り 基板は3段構成になっていて一番上の青い基板はBluetooth Module(BTM)です。 BTMのチップ印字消されていますが、いろいろググってみるとHC-05のコンパチ?っぽそうです。 モジュールは3.3Vで駆動されていますが、typは3.6~6Vらしいですね。 RT,TX,3.3V,GND,5Vは以下の位置関係のようです。 参考 アナログタコメータをつくる(1) OBD2スキャナ ArduinoとELM327でOBD取得する 接続 ELM327はスマホで動作確認はできていますので、PCとシリアル通信してみます。 USB-TTLデバイスを用意して、以下のように接続します。 ELM327 USB-TTL 5V 5V GND GND TX RX RX TX 通常は定番のFTDIの石を使うと思いますが、持っていないのでCH32V003用に持っているWCH-LinkEを使いました。 COMポートとして認識されるデバイスなら通信できそうです。 Arduino UNO R2のUSB-シリアル変換部分も同じように使うことができます。その場合、以下のように接続します。 ArduinoのTX(pin1)はUSB-シリアル変換部分のRXに、RX(pin0)はTXに繋がっているので、クロス接続にはしません。 以下↓にも記載しています。 NCP-HG100 を 楽天モバイル Band3 に固定する | atooshi-note ...

2025/02/08 · Last updated on 2025/03/28 · 8 min · 1582 words

Arduino I2C LCD2004 LiquidCrystal_I2C.h不使用

はじめに LiquidCrystal_I2C.hを使わず、LCD2004でHello Worldしました。 前回記事では、LiquidCrystal_I2C.hを使用してLCDを制御しました。 LCD2004やI2Cアダプタについては前回記事を御覧ください。同じものを使用します。結線も同じです。 Arduino I2C LCD2004 HelloWorld | atooshi-note ArduinoでLCDを制御する例を調べるとLiquidCrystal_I2C.hを使った記事がたくさんヒットしますが、LiquidCrystal_I2C.hを使わない例はあまり見かけませんでした。 RaspberrypiやPICやSTM32で駆動している例はそこそこ見つかりました。 気をつける点(自分めも) LiquidCrystal_I2C.hを使わない例としてはACM1602NIを駆動している例がありました。これもI2C接続ですが、LCDモジュールとI2Cアダプタがセットになっています。今回私が使用しているのはLCDとI2Cアダプタ(PCF8574T)が別で接続したものですのでプログラムそのままでは動きません。 以下はLiquidCrystal_I2C.hがいい感じにやってくれていますが、自分で組むときに気をつけた点です。 適切なディレイが必要 初期化手順が決まっている 4bitモードで制御する enable信号のL→H→Lは0.22us以上あける PCF8574TとLCD2004の結線 LCD DB7 DB6 DB5 DB4 バックライトのトランジスタのGate E R/W RS PCF8574T P7 P6 P5 P4 P3 P2 P1 P0 プログラム /* wire.h使用(i2c) #include <LiquidCrystal_I2C.h>は不使用 */ #include <Wire.h> #define lcdaddr 0x27 #define lcdEN 0b00000100 // Enable #define lcdBL 0b00001000 // Back light ON #define setDDRAMaddr 0b10000000 // Set DDRAM Address #define setRS 0b00000001 // RS=1 #define unsetRS 0b00000000 // RS=0 void lcdinit() { // 一旦8bitモードに設定(3回繰り返す) // 1回目 lcdwrite0(0x30,unsetRS); // Funcition Set DL=1:8bitバス delay(5); // Wait for more than 4.1 ms // 2回目 lcdwrite0(0x30,unsetRS); delayMicroseconds(150); // Wait for more than 100 µs // 3回目 lcdwrite0(0x30,unsetRS); delayMicroseconds(100); // Wait for more than 40 µs lcdwrite0(0x20,unsetRS); // 4bitモードに設定 Funcition Set DL=0:4bitバス lcdwrite(0x28,unsetRS); // 2行表示モードに設定 Funcition Set DL=0:4bitバス,Set N=1:2桁表示 lcdwrite(0x0F,unsetRS); // 表示ON/OFF D=1:文字表示ON,C=1:下線カーソルON,B=1:ブロックカーソルON lcdwrite(0x06,unsetRS); // エントリモードセット I/D=1:インクリメント lcdwrite(0x01,unsetRS); // 表示クリア lcdwrite(0x02,unsetRS); // カーソルホーム } // 8bit用 void lcdwrite0(byte bits,byte mode){ i2cwrite(bits | mode); } // 4bit用 void lcdwrite(byte bits,byte mode){ i2cwrite((bits & 0xF0) | mode); // 上位4bit i2cwrite(((bits << 4) & 0xF0) | mode); // 下位4bit } void i2cwrite(byte val){ Wire.beginTransmission(lcdaddr); Wire.write(val | lcdBL); delayMicroseconds(1); // 0.22us以上 Wire.write(val | lcdBL | lcdEN); delayMicroseconds(1); // 0.22us以上 Wire.write(val | lcdBL); Wire.endTransmission(); delayMicroseconds(100); // Wait for more than 40 µs とは言いつつ50usec待ちでは動かない 100usecぐらい余裕を持っておく } // row:行 col:列 void setCursor(int row, int col){ int row_offsets[] = {0x00, 0x40, 0x14, 0x54}; // 0から数え始め lcdwrite((col + row_offsets[row]) | setDDRAMaddr,unsetRS); } void lcdText(String s){ for(int i = 0; i < s.length(); i++){ lcdwrite(s.charAt(i),setRS); } } void setup() { delay(50); // Wait for more than 15 ms after VCC rises to 4.5 V Wire.begin(); lcdinit(); setCursor(0,0); // カーソルを0行目0列目に移動 lcdwrite(0x30,setRS); // 数字の0を出力 HD44780 Table 4 Correspondence between Character Codes and Character Patterns (ROM Code: A00) setCursor(1,1); lcdwrite(0x31,setRS); // 数字の1を出力 setCursor(2,2); lcdText("2_hello world!"); } void loop() { setCursor(3,0); lcdText("3_Hello World!"); delay(1000); setCursor(3,0); lcdText("3_World!"); delay(1000); } 結果 ...

2025/02/04 · Last updated on 2025/03/13 · 2 min · 325 words

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 LCDの制御ICは商品説明に hd44780,st7066,eqvチップ とあるので、業界標準になっている日立の超ロングセラー液晶コントローラーであるHD44780の互換ICが載っていると思われます。 I2CアダプタとLCDははんだ付けされておらず、別々で届きました。 LCDは18pinで以下のピンアサインになっています。 I2Cアダプタは16pinなので、pin1から合わせて、pin17,18がNCとなります。 I2Cアダプタ基板の表面しかパターンを追えてませんが、おそらく回路は以下記事と同じと思われます。 PCF8574Tを使ったLCD制御 DB0 から DB3は未接続で、DB4 から DB7は繋がっているため4bitモードだと思われます。 I2Cアダプタ(PCF8574T) PCF8574TはI2C接続のI/Oエキスパンダです。 青いポテンショメーター下のA0,A1,A2の空きランドでI2Cのスレーブアドレスを決定しますが、デフォルトでは3つとも開放なのでアドレスは0x27となります。 PCF8574Tのデータシートの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 UNO R2 I2Cアダプタ A4(SDA) SDA A5(SCL) SCL 5V VCC GND GND プログラム 色々書きましたが、LiquidCrystal_I2C.hを使う場合は細かいことは意識することなく表示することができます。(LiquidCrystal_I2C.hがいい感じにやってくれます) ...

2025/01/27 · Last updated on 2025/03/14 · 1 min · 126 words

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

はじめに 車両のOBDでデータを取りたいと思っていますが、車両で開発は大変なのでArduinoで車両をシミュレートする環境を作りました。 参考 以下を参考にさせていただきました。ありがとうございます。 環境 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個セット安いやつです。 KKHMF 3個 MCP2515 CAN バス モジュール TJA1050 SPI レシーバー Arduino AVR MCU ARM に対応 不良が混じっていることが多いみたいなのでモジュールを2つ使って動作確認をしました。 こちらは以下を参考にして動作確認をしました。ありがとうございます。 OBDケーブル について 以下を使用しました。 LoongGate OBD - II 16ピンオープンプラグワイヤを終了するには - OBD2 16ピンラウンド延長コネクタ診断ケーブル - 0.3メートル レビューには商品袋に記載のピンアサインと実際のピンアサインは違うとあったのでテスターチェックしましたが、商品袋に記載の通りでした。なので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 ...

2024/12/26 · Last updated on 2025/02/07 · 1 min · 150 words

ヘルシオAX-L1をArduinoで改造

中古のヘルシオAX-L1をメルカリで500円でゲットしました。 油汚れまくり、板金ボコボコ、プラパーツバキバキでしたが、壊れてなく(?)ラッキーな買い物でした。 しかし、使いづらいのがノブ 回すのですが、狙った番号にならない。通り過ぎちゃう。 なので、Arduinoで改造しました。 普段使うのは自動温めの3番,手動温めの29番なので、それを一瞬でできるようにプッシュスイッチをつけました。 ポチッとすると3番,29番になるような感じです。 ノブはロータリーエンコーダなので、パルス信号が出ています。 ポチった時にArduinoからパルス信号をだしてノブを模擬します。 3番がノブ3回転分なら、Arduinoから3回転分のパルスを出します。 いざヘルシオを開封 ノブの波形を見てみます。 適当に線を伸ばして 波形はしっかり2相ズレて出力されています。 回さないと3.3Vだったのでプルアップされています。 ノブ、スイッチの両方で動作するような回路にします。 といってもダイオードを入れただけです。 ダイオードのアノード側はヘルシオのロータリーエンコーダに並列に接続します。 スイッチを接続したポートはArduinoの内部プルアップとしました。 一応シミュレーションで見てみると大丈夫そうです。 スイッチを押してロータリーエンコーダを回していない時は、ダイオードが導通するためスイッチのプルアップ抵抗とロータリーエンコーダのプルアップ抵抗の両方から電流が流れます。 プルアップ抵抗が同値なら2倍の電流が流れますが、抵抗値はおそらく数kΩで電流は大した事ないので問題ないと思います。 ちなみにシミュレーション上の電圧などの定数は動作を見るためだけだったので適当です。 回路図はkicadで書きました。 githubにあげました。 atooshi-note/AX-L1 Arduinoのプログラムもgithubにあげてあります。 スイッチは以下の4つ実装します。 ノブ左1回転(left)、自動温め(atatame)、手動温め(syudou)、ノブ右1回転(right) 手動温めは29番で29回転は多いので後ろから数えています。 ノブ左1回転(left) 自動温め(atatame) 手動温め(syudou) ノブ右1回転(right) 動作が確認できたので、きれいに付けて ブレッドボードで最終動作確認して 基板に実装して固定。むき出し 便利!! 以上

2024/03/23 · Last updated on 2025/02/05 · 1 min · 39 words

Arduinoで1HzのPWMを生成する

ArduinoではanalogWrite(pin,value)でPWM変調した矩形波を出力することができます。 通常のPWM周波数は490Hzや997Hzなのですが、今回は、PWM周波数を1Hzとしたお話です。 analogWrite()は使わず、AVRライクな書き方をして、実現します。 ATmega328のデータシートとニラメッコしながらレジスタを設定します。 できればレジスタを触りたくなかったんですけど、それしか方法がない! PWMとは この辺は自分の覚書でもあるので、わかる方はすっ飛ばしてください。 PWMは Pulse Width Modulation の頭文字をとったもので、文字通りパルス幅変調です。 矩形波の幅を自在に調整して、平均電圧を上げたり下げたりできます。 例えば、5Vの電圧をONしっぱなし(5Vだしっぱなし)なら平均電圧はもちろん5Vです。 ですが、PWMで周期T中のオン時間Tonの割合Duty( = Ton / T )が50%の矩形波を出していれば、平均電圧は $$5V * 0.5 = 2.5V$$ となり、半分の電圧を出していることになります。 これをLEDに繋げれば、ちょっと薄暗く点きますね。 こんな感じでDutyを色々変えれば、電圧を調整できることがわかります。 analogWrite関数では、analogWrite(pin,value)のvalueがDutyに相当します。 valueは0~255(= 8bit = 2^8 = 256)の値とします。 なぜ1Hz? 詳しくは別記事で紹介予定ですが、低温調理器で使うSSRを制御するためです(^^) SSRはAC電圧(交流電圧)を制御します。 PWMは、DC電圧(直流電圧)ではDutyで平均値として取り出せますが、ACだとDuty=50%としても半分の電圧にはなりません。 また、50Hzという遅い周波数を制御するので、ArduinoデフォルトのPWM周波数では早すぎました。 そこで、1Hzとしました。 ArduinoのPWM ところでPWMはタイマーという機能で実現しています。 これはArduinoに限らず、PICやmbedなどの他のマイコンもそうです。 ArduinoはATmega328というMicrochip社(旧Atmel社)のマイコンをメインチップとして載せています。 Arduinoには(というか、ATmega328)には以下の3つのタイマー(正確にはTimer/Counter)があり、Arduinoではそれぞれ以下のような役割になっています。(Unoの例です) Timer/Counter ビット数 Arduinoでのpin番号 Arduinoでの役割 ArduinoでのPWM周波数 Timer0 8bit 5,6 普通のデジタルピン,delay(),millis(),micros() PWM出すなら997Hz Timer1 16bit 9,10 普通のデジタルピン PWM出すなら490Hz Timer2 8bit 3,11 普通のデジタルピン,tone() 同上 タイマーは3つのうちどれを使ってもいいですが、Arduinoの機能としてあるdelay()やtone()でTimer0やTimer2を使っているので、Timer0や2のPWM周波数を変更してしまうと影響が出てしまいます。 例えば、delay(500)と書けば500msのウエイトが本来発生しますが、変更すると同じように書いても500msではなくなってしまいます。 ですので、何も使ってなさそうなTimer1(9か10pinのどちらか)を使うことにします。 ...

2020/05/30 · Last updated on 2025/02/15 · 3 min · 608 words

macOS Catalinaでは中華Arduino互換機(CH340G)がそのまま認識された

Amazonで売っている(売ってた)HiLetgoのarduino互換機 ArduinoのUSBシリアル通信部分にはATmega16U2やFT***が使われていて、これらはMacでも標準で認識しますが、安いArduino互換機に使われているCH340Gは別途ドライバを当てないと認識しない、という考えだったのですが、 何もしなくても認識しました という話です(macOS Catalinaにて) 参考サイトさんにてMojaveにて別途ドライバが不要との紹介をされていたので、より新しいCatalinaでも認識するだろうと思ってやりましたらいけました。情報ありがとうございます(^^) 具体的には、ArduinoをMacに接続すると、シリアルポートに表示がでますので選択します。 私の場合は、”/dev/cu.usbserial-1420”とでました。 ボードはNano、プロセッサはOld Bootloaderとします。 ちなみに、石の表面には何も書いてませんでした(^^) 本稿とは直接関係ないですが、入力の3端子レギュレータはAMS1117-5Vを使用しています。(5V出力) http://www.advanced-monolithic.com/pdf/ds1117.pdf 本家?はナショセミのLM1117だと思いますが、こちらは20Vまで入力できますが、AMS1117は15Vまでしか入力できませんので注意が必要です。 どちらにしろ12Vで使うには問題なさそうです。(が15Vだと結構ギリなので電源の品質が悪くてリプルが12Vを超えるようなら要注意です。) 参考

2020/05/10 · Last updated on 2020/05/10 · 1 min · 16 words