• 車種別
  • パーツ
  • 整備手帳
  • ブログ
  • みんカラ+

zip********のブログ一覧

2024年01月28日 イイね!

1.3インチのOLEDを試してみる

1.3インチのOLEDを試してみる430タイマーの試作レビューで画面がもうちょっと大きいと良いという声が聞こえてきたので、ちょっと調べてみました。
同じ128*64ドットで0.96インチと1.3インチのものがあるようです。
ただ、1.3インチはSH1106で多少クセがあるようです。
ピンの配列もGNDとVCCが入れ替わってるものも多いので注意が必要です。
0.96インチはSSD1306ですのでネット上に豊富に情報がありますが、
SH1106はあまり情報がない印象です。

プログラムもSSD1306仕様では動かないので全てSH1106用に変更しないとダメ見たいです。
面倒くさい!!!

SSD1306Asciiですが、よく見たらSH1106にも対応していました。以下のように書き換えたところうまく表示できることを確認しました。よかった😅
//oled.begin(&Adafruit128x64, OLED_ADDRESS);
oled.begin(&SH1106_128x64, OLED_ADDRESS);

alt
左が0.96インチ、右が1.3インチの比較です。

GyverOLED-1.6.1というライブラリを試してみました。
開発元がロシアっぽくてロシア語読めない!となっていましたが、
ChatGPTに資料を読み込ませたところ、なんとか使えそうな気がしてきました。

結構軽そうなのでArduino NANOでも動かせそうです。

430タイマーは画面の表示が180度回転した状態で動作させるので
まずは回転表示が可能かどうか調べてみました。

alt
↑ 通常版


alt
↑ oled.flipH(true); // 画面を水平に反転

alt

↑ oled.flipV(true); // 画面を垂直に反転

alt
oled.flipH(true); // 画面を水平に反転
oled.flipV(true); // 画面を垂直に反転

合わせると180度回転になりました。
Posted at 2024/01/28 18:33:21 | コメント(0) | トラックバック(0) | Arduino | 日記
2022年11月28日 イイね!

LCD 1602A バックライト調整(PWM制御)

LCD 1602A バックライト調整(PWM制御)
430タイマーで使用していた0.96インチのOLEDですが、長期間使っていると劣化し画面の輝度が著しく低下するという問題があるということが分かってきました。

そこで画面をLCD1602Aと入替するべく、表示のテストを行いました。
I2Cの変換モジュールがはんだ付けされているタイプのものなのですが、
これがやたらバックライトが明るいのです。
夜間に走行するのにこんなにバックライトが明るいと運転の邪魔になりそうなのでバックライトの明るさを制御できないか、少し考えてみました。
可変抵抗を後付けするのは部品点数が増えるのであまりやりたくないので他の方法を考えます。
alt
バックライトのLEDは100Ωの抵抗がデフォルトでついていて、VCCの電源が直接供給されてる感じです。


最初は、lcd.backlight()と、lcd.noBacklight()を高速に交互に呼び出してPWM制御っぽくしてたのですが、なんかうまくないので、LCDのバックライトにArduinoの機能で直接PWM制御した信号を入れるようにしてみました。
LCDのバックライトには100Ωの抵抗が既についてるので、
ArduinoのD6ピンと、1602A I2Cモジュールのバックライトスイッチ端子の片側を繋げるだけです。
alt

あとは、pinMode(6,OUTPUT);でD6をアウトプットにして、
analogWrite(6, 20);みたいな感じでPWM制御してやればバックライトの明るさも自由自在です。

//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display


int brightness = 0;
#define READ_INTERVAL 20//ms
#define SW_PIN 7
#define LED_PIN 6

unsigned long timer, old_timer;
bool states, value, old_value;
char str[32];

void setup()
{
  lcd.init();                      // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("000Hello, world!");
  lcd.setCursor(2,1);
  lcd.print("Ywrobot Arduino!");
   lcd.setCursor(0,2);
  lcd.print("Arduino LCM IIC 2004");
   lcd.setCursor(2,3);
  lcd.print("Power By Ec-yuan!");

    pinMode(SW_PIN, INPUT_PULLUP);//入力
    pinMode(LED_PIN,OUTPUT);//LCDのLED
}


void loop()
{
  //READ_INTERVAL[ms]毎にスイッチの読取り
  timer = millis();
  if ( (timer - old_timer) >= READ_INTERVAL) {
    old_timer = timer;
    value = !(digitalRead(SW_PIN));//SW (ON=1 / OFF=0)
  }

  //スイッチの状態を取得
  int sw_states = 0;
  if (value == HIGH && old_value == LOW) {
    sw_states = 1;//スイッチが押された瞬間
  } else if (value == LOW && old_value == HIGH) {
    sw_states = 2;//スイッチを離した瞬間
  } else if (value == HIGH && old_value == HIGH) {
    sw_states = 3;//スイッチが押されている
  } else {
    sw_states = 0;//スイッチが押されていない
  }
  old_value = value;

  //スイッチの状態に応じて動作を変更
  switch (sw_states) {
    case 0://スイッチが押されていない
      //states = LOW;
      break;
    case 1://スイッチが押された瞬間
      //states = !states;
      BrightnessCHG();
      sprintf(str, "%03dHello, world!", brightness);
      lcd.setCursor(0,0);
      lcd.print(str);
      break;
    case 2://スイッチを離した瞬間
      //states = !states;
      break;
    case 3://スイッチが押されている
      //states = HIGH;
      break;
  }
}

void BrightnessCHG(){
  brightness += 17;
  if (brightness > 255){
    brightness = 0;
  }
  analogWrite(LED_PIN, brightness);
}

Posted at 2022/11/29 00:16:10 | コメント(0) | Arduino | 日記
2022年11月17日 イイね!

いすゞ 07フォワードでCAN受信 430タイマーの作成8

いすゞ 07フォワードでCAN受信 430タイマーの作成8
alt
約1年間が開いてしまいましたが、ブレッドボードの仮置きからユニバーサル基板でなんとかそれっぽい感じに持ってくことができました。

ケースはダイソーで110円で売ってた小物入れです。テキトーに目で採寸してアクリルカッターでガシガシ切ってきます。マスキングも、やすり掛けもいたしません。

430タイマーをトラックから取り外すとき配線を外すのが面倒だなと思っていたので、
CAN信号と電源はLANケーブルを流用することにしました。
秋月電子でLANコネクタDIP化キットみたいのが1セット200円(高い!)で売ってたので使ってみました。OBD2コネクタ側にも使ってるので合わせて400円です。いい値段しただけあって、とっても便利になりました。
作成途中、自分の悪い癖が出て固定が面倒になってきたので固定にホットボンドを使ってしまいました。おそらく夏場の炎天下で溶ける可能性大です。まあその時はその時で(笑)

約1年テストしてみて、430タイマーの演算に関してはバグは出てこなかったです。
見守りくんの見にくい停車分数表示ともズレは出なかったのである程度は信頼できると思います。
残りの運行時間がリアルタイムで表示できる装置は自分が確認できる範囲では市販されてないようなので、かなり実用的で満足度が高いものが作れたと思います。


肝心のタイマー部分はブレてかなり見にくくなってますが、
完成品の実働部分を撮影してみました。
シフトアップランプと90キロリミッタランプの動きがなかなか面白いです。
&lt;br /&gt;


alt
alt
 

Posted at 2022/11/17 20:20:08 | コメント(0) | トラックバック(0) | Arduino | 日記
2022年02月20日 イイね!

Arduinoでdelayを使わずチャタリング回避しスイッチだけで反転する方法

Arduinoでdelayを使わずチャタリング回避しスイッチだけで反転する方法
Arduinoで遊んでいて、スイッチを使い始めました。
スイッチを押すと、状態反転させたいのですが、チャタリングが起きてうまいこと動作しません。

delayを使うと画面表示等が止まってしまうためなにか方法はないかと思い、検索してみたが、殆どdelayやwhileでフックするスケッチしかなかったので、自分なりに考えて書いてみました。

カップリングコンデンサも必要ありません。
スイッチのチャタリングが20ms以内に終わって安定するならほぼ確実に動作するはずです。

INPUT_PULLUPしているので、スイッチは7番ピンとGNDを繋ぐだけです。
スイッチがなければ、7番ピンに繋いだワイヤーをGNDとチョンチョンさせれば動作確認できます。
LEDは適当に200~300Ωくらいの抵抗を5番ピンの出力にかましてください。



#define LED_PIN 5
#define SW_PIN 7
#define READ_INTERVAL 20//ms

void setup() {
  pinMode(LED_PIN, OUTPUT);//LED出力
  pinMode(SW_PIN, INPUT_PULLUP);//入力
}

unsigned long timer, old_timer;
bool states, value, old_value;
void loop() {

  //READ_INTERVAL[ms]毎にスイッチの読取り
  timer = millis();
  if ( (timer - old_timer) >= READ_INTERVAL) {
    old_timer = timer;
    value = !(digitalRead(SW_PIN));//SW (ON=1 / OFF=0)
  }

  //スイッチの状態を取得
  int sw_states = 0;
  if (value == HIGH && old_value == LOW) {
    sw_states = 1;//スイッチが押された瞬間
  } else if (value == LOW && old_value == HIGH) {
    sw_states = 2;//スイッチを離した瞬間
  } else if (value == HIGH && old_value == HIGH) {
    sw_states = 3;//スイッチが押されている
  } else {
    sw_states = 0;//スイッチが押されていない
  }
  old_value = value;

  //スイッチの状態に応じて動作を変更
  switch (sw_states) {
    case 0://スイッチが押されていない
      //states = LOW;
      break;
    case 1://スイッチが押された瞬間
      states = !states;
      break;
    case 2://スイッチを離した瞬間
      //states = !states;
      break;
    case 3://スイッチが押されている
      //states = HIGH;
      break;
  }

  //LEDにステータス反映
  digitalWrite(LED_PIN, states);
}

Posted at 2022/02/20 22:03:55 | コメント(0) | トラックバック(0) | Arduino | パソコン/インターネット
2022年01月28日 イイね!

いすゞ 07フォワードでCAN受信 430タイマーの作成6

いすゞ 07フォワードでCAN受信 430タイマーの作成6
CANにリクエストするのは失敗しましたが、お目当ての車速がゲットできたので完成に一歩近づいてきました。

必要なライブラリは以下の2つ。先にインストールしておきます。
・greiman / SSD1306Ascii
・coryjfowler / MCP_CAN_lib

SSD1306Asciiはスケッチ量がとても軽いのが特徴で自分が失敗して購入した168pでも26%ほどの余裕が生まれました。Adafruit純正やu8glibでは容量的に厳しいものがありました。

ライブラリの開発者様には本当に感謝ですね。
動作機序なんてほとんど理解できていなくてもそれなりのものが簡単に仕上がるのってすごいと思います。

DS1307のRTCモジュールが届いたので、ブレッドボードで実験してみました。iPhoneのストップウォッチと並べてみてしばらく眺めていたところ、3分に1回程度ランダムに1秒割り込みが漏れてしまう現象が発生していたので、コードを書き直しました。
6つのフラグ変数を1バイトで合わせて処理していたのでそれが原因のようでした。
(下記のコードは修正済みのものです)

しばらくiPhoneのストップウォッチと見比べていましたが気になるようなズレはなかったので問題なく動作しているものと思われます。

DS1307の乗ったTiny RTC I2Cモジュール、電池ホルダーを挟んで両側にピンを接続できるようになっています。どっちに繋いでも同じように動作します。
SQWの1Hz信号を使うので7つ開いてるほうにピンヘッダをはんだ付けしました。
ネットで探すとどの写真でも5つ開いてるほうにピンヘッダを取り付けている例しか見ることができなかったので反対側は使えないのかと思っていましたがそうではなさそうです。

容量が大きいArduino nano 328p版も別の基板から引っぺがしてきたのでこれで好き放題プログラムが書けるようになりました。

SQWの信号を割り込ませるだけで、RTCモジュールの時計機能を全く使用していないので、かなり勿体ない気がしています。
オーバーフローは全く考慮していないので、停車時間が999分を超えると表示がバグります。

2022/10/26 別回路用修正済みコード

//LED関係

//LED関係
#define LED_PIN 6
#define BLINK_INTERVAL 50//ms
bool states;

//RTC関係
#include
#define RTC_ADDRESS 0x68

//CAN関係
#include
#include
#define CAN0_INT 2
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
short int rpm = 0;
short int gas_pedal = 0;
bool brk = 0;
float kmh = 0;
MCP_CAN CAN0(10); //CS pin10

//OLED関係
#include "SSD1306AsciiAvrI2c.h"
#define OLED_ADDRESS 0x3C
SSD1306AsciiAvrI2c oled;
//タイマー関係
#define H4 14400UL//4時間分の秒数4*60*60
short int h4Timer = H4 - 1UL; //H4;
unsigned short int stopTimer = 0;//停止時間計測 秒
short int stopKakutei = 0;//確定した停車時間の積算
short int stopKakutei_old = 0;//停止時間計測 h4Timerに加算検出用
unsigned int timerBlink;
char str[32];//OLED文字バッファ
volatile bool Flg_1HZ = false;
bool Flg_STOP = false;
short int stopTimeBuf[3] = {0, 0, 0};

void setup() {
pinMode(LED_PIN, OUTPUT);//LED出力

CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ);
CAN0.setMode(MCP_NORMAL);
pinMode(CAN0_INT, INPUT);

oled.begin(&Adafruit128x64, OLED_ADDRESS);
//RTC初期化 pin3は、SQW1秒クロック割り込み
iniRTC();
pinMode(3, INPUT_PULLUP);//pin3
attachInterrupt(1, sec_cnt, FALLING);//pinD3

/*
//デバッグモード
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, OUTPUT);

//OLED割り込み
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, oled_prn, FALLING);//pinD2-D9
*/
}
void loop() {

CAN0.readMsgBuf(&rxId, &len, rxBuf);
switch (rxId) {
case 0x0c9:
rpm = ((rxBuf[1] * 256) + rxBuf[2]) / 4;//回転数
gas_pedal = (rxBuf[4] * 100) / 256;//アクセルペダル踏込み量
brk = rxBuf[5];//ブレーキのオフオン
break;
case 0x3E9:
kmh = ((rxBuf[0] * 100) + rxBuf[1]) * 0.04;//車速
break;
}

/*//デバッグモード
rpm = 0;
brk = 0;
if(!digitalRead(7)){
rpm = 1700;
}
if(!digitalRead(8)){
brk = 1;
}
*/

//回転数が一定値以上でLED警告
states = LOW;
if (kmh < 55){//55キロ未満 一般道シフトアップリミット
if(rpm >= 1677){
states = HIGH;
}
}else if(kmh < 70){//70キロ未満 一般道 5速60キロリミット
if(rpm >= 1480){
states = HIGH;
}
}else{//70キロ以上 高速道90キロリミット
if(rpm >= 1620){
states = HIGH;
}
}

//rpm = 3000 * (1+(float)gas_pedal) / 100;//デバッグ用

//ブレーキ操作時
if (brk == 1) {
switch (gas_pedal) {
case 99:
software_RESET();
break;
default:
//ブレーキのみ踏んでいる場合
digitalWrite(LED_PIN, LOW);
break;
}
}else{//アクセル操作時
digitalWrite(LED_PIN, !(states));
}

//車速が入ればflgオン
if (kmh == 0) {
Flg_STOP = true;
} else {
Flg_STOP = false;
}
/*タイマカウント部*/
if (Flg_1HZ) {
Flg_1HZ = false;
//4時間タイマーカウントダウン
h4Timer --;
if (h4Timer <= 0) { //4時間タイマーがゼロ時の動作
h4Timer = 0;
}

//停車時間タイマカウントアップ
//停車中---------------
if ( Flg_STOP ) {
//停車カウンタインクリメント
stopTimer += 1;

if(stopTimer >= 60000){//999分59秒より大きくなったら1秒戻す
stopTimer -= 1;
}

//今の有効な停車分数+バッファの合計停車分
stopKakutei = stopTime_calc( stopTimer ) + stopTime_sum();
if (stopKakutei >= 30) { //30分以上は30分固定
stopKakutei = 30;
h4Timer ++;//h4タイマー停止
}
//確定した有効な停車分数をh4タイマーに戻す
if (stopKakutei != stopKakutei_old) {
h4Timer += (stopKakutei - stopKakutei_old) * 60;
stopKakutei_old = stopKakutei;
}
}//走行中-----------------
else {
//30分の休憩確定で初期化リセット
if (stopKakutei >= 30) {
software_RESET();
}
//30分未満の有効な停車分数をバッファに書き込み
stopTimeBuf_write( stopTime_calc( stopTimer ) );
stopTimer = 0;
}
}
/*----------------------------*/

//noInterrupts(); //割り込み禁止
//oled_prn();
//interrupts();
}
//RTCの初期化
void iniRTC() {
Wire.beginTransmission(RTC_ADDRESS);//DS1307
Wire.write(0x00);//Register 先頭アドレス
Wire.write(0x00);//RTC 0秒開始
Wire.write(0x00);//RTC 分
Wire.write(0x00);//RTC 時
Wire.write(0x00);//RTC 週
Wire.write(0x00);//RTC 日
Wire.write(0x00);//RTC 月
Wire.write(0x00);//RTC 年
Wire.write(0x10);//RTC SQW 1Hz
Wire.endTransmission();
}

void oled_prn(){
oled.set1X();
oled.setFont(Adafruit5x7);
oled.setCursor(0, 0);
sprintf_P(str, PSTR("\nHR4\nTMR"));
oled.print(str);
//車速、回転数、ブレーキ,アクセルペダル表示
oled.setCursor(0, 7);
sprintf(str, "%3dkm %4drpm B%d A%2d", (int)kmh, rpm, brk, gas_pedal);
oled.print(str);
//STOP TIMEの文字表示
oled.setCursor(75, 4);
oled.print(F("STOP"));
oled.setCursor(75, 5);
oled.print(F("TIME"));
//H4タイマカウンタ表示
oled.setFont(lcdnums14x24);
sprintf_P(str, PSTR("%d:%02d:%02d"), s_to_h(h4Timer) , s_to_m(h4Timer), s_to_s(h4Timer) );
oled.setCursor(20, 0);
oled.print(str);
//停車時間タイマカウンタ表示
oled.setFont(lcdnums12x16);
oled.setCursor(0, 4);
if (stopTimer <= 0) {
sprintf_P(str, PSTR("---:--"));
} else {
sprintf_P(str, PSTR("%03d:%02d"), s_to_m(stopTimer) + (s_to_h(stopTimer) * 60), s_to_s(stopTimer) );
}
oled.print(str);
//停車時間確定カウンタ表示
oled.set2X();
oled.setFont(Adafruit5x7);
oled.setCursor(100, 4);
if (stopKakutei == 0) {
sprintf_P(str, PSTR(" "));
} else {
sprintf_P(str, PSTR("%d"), stopKakutei);
}
oled.print(str);

}
void sec_cnt() { //割り込み用(1秒クロック)
Flg_1HZ = true;
oled_prn();
}
short int stopTime_calc(unsigned short int i) { //引数:停車(秒数) 戻値:有効な停車(分数)
i = s_to_m(i) + (s_to_h(i) * 60); //分数に変換
if (i >= 30) {
i = 30;
} else if (i >= 20) {
i = 20;
} else if (i >= 15) {
i = 15;
} else if (i >= 10) {
i = 10;
} else {
i = 0;
}
return i;
}

short int stopTime_sum() { //バッファの合計値(分数)を求める
short int sum = 0;
for (int x = 0; x < 3; x++) {
sum += stopTimeBuf[x];
}
return sum;
}
void stopTimeBuf_write(short int i) { //バッファ未使用領域に停車(分数)を書き込む
for (int x = 0; x < 3; x++) {
if (stopTimeBuf[x] == 0) {
stopTimeBuf[x] = i;
break;
}
}
}
void software_RESET() { //強制リセット
asm volatile (" jmp 0");
}
void digitalWrite_A(int pin, bool val, float per){//LED明るさ調整
analogWrite(pin, (255*(per/100)) * val );
}
/*----- タイマー演算用 -----*/
int s_to_h(unsigned long s) {
return s / 3600;
}
int s_to_m(unsigned long s) {
return (s % 3600) / 60;
}
int s_to_s(unsigned long s) {
return s % 60;
}
/*----------------------------*/

Posted at 2022/02/06 00:07:06 | コメント(0) | トラックバック(0) | Arduino | パソコン/インターネット

プロフィール

「[整備] #フォワード ArduinoでCAN通信できるプリント基板を作って組立 (MCP2515) https://minkara.carview.co.jp/userid/3423019/car/3226320/7545498/note.aspx
何シテル?   10/29 00:19
zip********です。よろしくお願いします。
みんカラ新規会員登録

ユーザー内検索

<< 2024/5 >>

   1234
567891011
12131415161718
19202122232425
262728293031 

ブログカテゴリー

愛車一覧

いすゞ フォワード いすゞ フォワード
いすゞ フォワードに乗っています。

過去のブログ

2024年
01月02月03月04月05月06月
07月08月09月10月11月12月
2023年
01月02月03月04月05月06月
07月08月09月10月11月12月
2022年
01月02月03月04月05月06月
07月08月09月10月11月12月
ヘルプ利用規約サイトマップ
© LY Corporation