' ' ********************************************** ' * * ' * AVR & BASCOM-AVR トレーニング・ボード * ' * 初期設定 Ver.1.01 * ' * * ' * AVR is using ATmega88P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2010.10.29 * ' ********************************************** ' $regfile = "m88pdef.dat" '使用するAVRを設定。 $crystal = 16000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' * ポート名の定義 * ' Sw_1 Alias Pind.0 'スイッチ[1]の接続ポート。 Sw_2 Alias Pind.1 'スイッチ[2]の接続ポート。 Sw_3 Alias Pind.2 'スイッチ[3]の接続ポート。 Sw_4 Alias Pind.3 'スイッチ[4]の接続ポート。 ' Led_1r Alias Portd.4 'LED1[赤]の接続ポート。 Led_2g Alias Portd.5 'LED2[緑]の接続ポート。 Led_3y Alias Portd.6 'LED3[黄]の接続ポート。 Led_4b Alias Portd.7 'LED4[青]の接続ポート。 Sp_out Alias Portc.5 'スピーカーの接続ポート。 ' Ad_photo Alias 0 '光センサーのA/Dコンバータ・チャネル番号。 Ad_thermo Alias 1 '温度センサーのA/Dコンバータ・チャネル番号。 Ad_ain1 Alias 2 '測定入力[1]のA/Dコンバータ・チャネル番号。 Ad_ain2 Alias 3 '測定入力[2]のA/Dコンバータ・チャネル番号。 Ad_ain3 Alias 4 '測定入力[3]のA/Dコンバータ・チャネル番号。 Ad_spin Alias 5 'スピーカー入力のA/Dコンバータ・チャネル番号。 ' ' * ポートの初期設定 * ' Config Led_1r = Output 'LED1の接続ポートを出力に設定する。 Config Led_2g = Output 'LED2の接続ポートを出力に設定する。 Config Led_3y = Output 'LED3の接続ポートを出力に設定する。 Config Led_4b = Output 'LED4の接続ポートを出力に設定する。 Config Sp_out = Output 'スピーカーの接続ポートを出力に設定する。 ' Set Portd.0 'スイッチ[1]の接続ポートをプルアップする。 Set Portd.1 'スイッチ[2]の接続ポートをプルアップする。 Set Portd.2 'スイッチ[3]の接続ポートをプルアップする。 Set Portd.3 'スイッチ[4]の接続ポートをプルアップする。 Didr0 = &B00111111 'デジタル入力禁止レジスタの設定。 ' ' * LCDの初期設定 * ' Config Lcdmode = Port 'LCDを4ビットのポートモードに設定。 Config Lcdbus = 4 'LCDデータバスを4bitに設定。 Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 'LCDのポート割り当て。 Config Lcdpin = Pin , Db6 = Portb.1 , Db7 = Portb.0 Config Lcdpin = Pin , E = Portb.4 , Rs = Portb.5 Config Lcd = 16 * 2 'LCD表示を16文字2行に設定。 Cls 'LCD表示をすべて消去。 ' ' * A/Dコンバータの初期設定 * ' Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの設定。 Start Adc 'A/Dコンバータに電源を供給。 ' ' ↓********************************************↓ ' ↓ これ以降に各自のプログラムを作成して下さい ↓ ' ↓********************************************↓ ' ' ' ****************************************** ' * HX711 (24bit A/Dコンバータ) * ' * + * ' * ロードセル 20kg [SC133-20kg] 重量計 * ' * * ' * Copyright O-Family 2018. 9.15 * ' ****************************************** ' ' Ver 0.01 初回公開バージョン。 2018. 9.15 ' Ver 2.01 20Kgの[SC133]用に変更。 2021.11.26 Const Prgver = " 2.01" 'プログラム・バージョン。 ' ' * ポート名の定義 * ' Hx711_clk Alias Portd.7 'HX711の[PD_SCK]ピンの接続ポート。 Hx711_dat Alias Pind.3 'HX711の[DOUT]ピンの接続ポート。 ' ' * 変数の宣言 * ' Dim Hx711ad As Long 'HX711から取り出した生のA/Dデータ。 Dim Hx711avg As Long 'HX711のA/D値を移動平均した値。 Dim Hx711count As Byte 'HX711のA/Dデータ取り出しカウンター。 Dim Average(16) As Long '移動平均用バッファー。 Dim Avgpoi As Byte '移動平均のポインター。 Dim Avgsum As Long '移動平均の合計値。 Dim Zeroadj As Long 'ゼロ調整の差分値。 Dim Stablecount As Byte '安定マーク表示までのカウント数。 Dim Lastvalue As Long '前回の測定値。 Dim Sensorcal As Long 'ロードセル・センサーからグラム換算する校正値。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 Dim Templ1 As Long '汎用テンポラリ変数 Long型 No.1 Dim Tempstr As String * 40 '汎用テンポラリ変数 String型 ' Dim Dummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eepprgid As Eram Long 'EEPROM プログラムのID。 Dim Eepsensorcal As Eram Long 'EEPROM ロードセル・センサーからグラム換算する校正値。 ' ' * ポートの初期設定 * ' Config Hx711_clk = Output 'HX711の[PD_SCK]ピンの接続ポートを出力に設定する。 Reset Hx711_clk 'HX711の[PD_SCK]ピンを[L]にする。(通常動作モードにする) Config Hx711_dat = Input 'HX711の[DOUT]ピンの接続ポートを入力に設定する。 ' ' * EEPROMのデータを確認する * ' If Eepprgid <> &H32375848 Then 'If EEPROMが初期値か? Then Eepprgid = &H32375848 'EEPROM プログラムのID。[HX72] Eepsensorcal = 10737 'EEPROM ロードセル・センサーからグラム換算する校正値。 End If Sensorcal = Eepsensorcal ' ' * 20回の測定を行い、ゼロ調整用の差分を用意する * ' Cursor Off 'LCDのカーソルをオフにする。 Avgpoi = 1 '移動平均のポインターを初期化する。 Locate 1 , 1 'ゼロ調整中の表示。 Lcd "Zero Adjustment" ' For Temp1 = 1 To 20 '20回の測定を行い移動平均する。 Do Loop Until Hx711_dat = 0 'HX711の[DOUT]ピンが[L]になった(変換終了)か? ' Gosub Hx711get 'HX711のチャンネルAから128の利得でA/Dデータを取り出す。 Gosub Hx711movavg 'HX711のA/D変換データを移動平均する。 Locate 2 , 1 Lcd Hex(hx711avg) 'A/Dの平均値をLCDに表示する。 Next Temp1 ' Zeroadj = 0 - Hx711avg '現在の測定値からゼロ調整の差分を計算する。 Stablecount = 0 '安定マークの表示カウント数を初期化する。 Lastvalue = 0 '前回の測定値を初期化する。 Cls 'LCD表示をすべて消去する。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: ' ' * 重量の測定 * ' If Hx711_dat = 0 Then 'If HX711の[DOUT]ピンが[L]になった(変換終了)か? Then Gosub Hx711get 'HX711のチャンネルAから128の利得でA/Dデータを取り出す。 Locate 1 , 1 Lcd Hex(hx711ad) 'HX711の生のA/D値をLCDに表示する。 ' Gosub Hx711movavg 'HX711のA/D変換データを移動平均する。 Locate 2 , 1 Lcd Hex(hx711avg) 'A/Dの平均値をLCDに表示する。 ' Templ1 = Hx711avg + Zeroadj 'ゼロ調整の差分を計算する。 ' Templ1 = Templ1 * 100 'グラム換算の小数点桁上げのために100倍する。 Templ1 = Templ1 / Sensorcal 'ロードセル・センサーのA/D値からグラム換算する。 ' Locate 2 , 10 Tempstr = Str(templ1) '数値変数を文字変数に変換する。 If Templ1 < 0 Then 'If 表示値がマイナスか? Then Lcd Format(tempstr , " 0") ; "g" 'マイナスの重量をLCDに表示する。 Else 'プラスの場合。 Lcd Format(tempstr , " 0") ; "g" 'プラスの重量をLCDに表示する。 End If ' ' * 安定マーク[*]の表示 * ' Locate 1 , 10 If Templ1 = Lastvalue Then 'If 前回の測定値との差が無いか? Then Stablecount = Stablecount + 1 '安定マーク表示までのカウント数を加算する。 If Stablecount > 5 Then 'If 安定マーク表示のカウント数に達したか? Then Stablecount = 5 Lcd "*" '安定マーク[*]を表示する。 End If Else '前回の測定値から変化している場合。 Lastvalue = Templ1 '現在の測定値を保管する。 Stablecount = 0 '安定マークの表示カウント数を初期化する。 Lcd " " '安定マーク[*]を消去する。 End If End If ' ' * スイッチの処理 * ' Debounce Sw_1 , 0 , Sw1on 'If [SW1]が押されたか? Then Debounce Sw_2 , 0 , Sw2on 'If [SW2]が押されたか? Then Goto Main '-------------------------------------------------------------------------------------------------- ' ' ****************** ' * [SW1] ゼロ調整 * ' ****************** ' Sw1on: Zeroadj = 0 - Hx711avg '現在の測定値を[0.0g]にする。 Stablecount = 0 '安定マークの表示カウント数を初期化する。 Goto Main '-------------------------------------------------------------------------------------------------- ' ' ******************************** ' * [SW2] センサーの出力誤差調整 * ' ******************************** ' Sw2on: Cls 'LCD表示をすべて消去する。 Lcd "Calibration" Bitwait Sw_2 , Set '[SW2]が離されるまで待つ。 Temp1 = 0 'スイッチ長押し検出カウンター。 ' Sw2on1: Debounce Sw_1 , 0 , Calsw1on 'If [SW1]が押されたか? Then Debounce Sw_2 , 0 , Calsw2on 'If [SW2]が押されたか? Then Debounce Sw_3 , 0 , Calsw3on 'If [SW3]が押されたか? Then ' If Hx711_dat = 0 Then 'If HX711の[DOUT]ピンが[L]になった(変換終了)か? Then Temp2 = Sw_2 And Sw_3 '[SW2]と[SW3]の長押しを検出する。 If Temp2 = 0 Then 'If [SW2]か[SW3]が押されているか? Then Temp1 = Temp1 + 1 If Temp1 > 10 Then '[SW2]か[SW3]が押されてから1秒経過したか? Then Temp1 = 10 If Sw_2 = 0 Then 'If [SW2]が押されているか? Then If Sensorcal < 21000 Then 'If 上限ではないか? Then Sensorcal = Sensorcal + 10 'ロードセル・センサーのグラム換算値を加算する。 End If Else If Sensorcal > 1000 Then 'If 下限ではないか? Then Sensorcal = Sensorcal - 10 'ロードセル・センサーのグラム換算値を減算する。 End If End If End If End If ' Gosub Hx711get 'HX711のチャンネルAから128の利得でA/Dデータを取り出す。 Gosub Hx711movavg 'HX711のA/D変換データを移動平均する。 Templ1 = Hx711avg + Zeroadj 'ゼロ調整の差分を計算する。 ' Templ1 = Templ1 * 100 'グラム換算の小数点桁上げのために100倍する。 Templ1 = Templ1 / Sensorcal 'ロードセル・センサーのA/D値からグラム換算する。 ' Locate 2 , 3 Tempstr = Str(templ1) '数値変数を文字変数に変換する。 If Templ1 < 0 Then 'If 表示値がマイナスか? Then Lcd Format(tempstr , " 0") ; "g" 'マイナスの重量をLCDに表示する。 Else 'プラスの場合。 Lcd Format(tempstr , " 0") ; "g" 'プラスの重量をLCDに表示する。 End If ' Tempstr = Str(sensorcal) '数値変数を文字変数に変換する。 Locate 2 , 12 'ロードセル・センサーのグラム換算値を表示する。 Lcd Format(tempstr , " 0") End If Goto Sw2on1 ' ' * [SW1]校正終了 * ' Calsw1on: Eepsensorcal = Sensorcal 'EEPROMに保管する。 Stablecount = 0 '安定マークの表示カウント数を初期化する。 Cls 'LCD表示をすべて消去する。 Goto Main ' ' * [SW2]校正値を加算 * ' Calsw2on: If Sensorcal < 21000 Then 'If 上限ではないか? Then Sensorcal = Sensorcal + 1 'ロードセル・センサーのグラム換算値を加算する。 End If Temp1 = 0 'スイッチ長押し検出カウンターを初期化する。 Goto Sw2on1 ' ' * [SW3]校正値を減算 * ' Calsw3on: If Sensorcal > 1000 Then 'If 下限ではないか? Then Sensorcal = Sensorcal - 1 'ロードセル・センサーのグラム換算値を減算する。 End If Temp1 = 0 'スイッチ長押し検出カウンターを初期化する。 Goto Sw2on1 '================================================================================================== ' ' ******************************************************************** ' * HX711のチャンネルAから128の利得でA/Dデータを取り出すサブルーチン * (Hx711ad = 2の補数形式24bit) ' ******************************************************************** ' Hx711get: Hx711ad = 0 For Hx711count = 23 To 0 Step -1 '24bitのデータを取り出す。 Set Hx711_clk 'HX711の[PD_SCK]ピンを[H]にする。 Waitus 1 '[H]の期間。(T3=1uS) Hx711ad.hx711count = Hx711_dat 'HX711の[DOUT]ピンのデータを各ビットに配置する。 Reset Hx711_clk 'HX711の[PD_SCK]ピンを[L]にする。 Waitus 1 '[L]の期間。(T4=1uS) Next Hx711count ' ' * 25個目のクロックパルスを送る (次回の変換をチャンネルA・利得を128に設定する) * ' Set Hx711_clk 'HX711の[PD_SCK]ピンを[H]にする。 Waitus 1 '[H]の期間。(T3=1uS) Reset Hx711_clk 'HX711の[PD_SCK]ピンを[L]にする。 Waitus 1 '[L]の期間。(T4=1uS) ' If Hx711ad.23 = 1 Then 'A/Dの24bit値がマイナス値か? Then Hx711ad = Hx711ad Or &HFF000000 '32bitのマイナス値にする。 End If Return '--------------------------------------------------------------------------------------------------- ' ' ************************************************** ' * HX711のA/D変換データを移動平均するサブルーチン * (Hx711avg = 16個の移動平均) ' ************************************************** ' Hx711movavg: Avgsum = Avgsum - Average(avgpoi) '一番古いデータを減算する。 Average(avgpoi) = Hx711ad '移動平均バッファーに格納する。 Avgsum = Avgsum + Hx711ad '新しいデータを合算する。 ' Avgpoi = Avgpoi + 1 '移動平均ポインターを更新する。 If Avgpoi > 16 Then 'If ポインターが上限か? Then Avgpoi = 1 End If ' Hx711avg = Avgsum Shift Hx711avg , Right , 4 , Signed '16個の移動平均を取る。 Return ' ' End