スケート用の速度計。 絶望

背景



良い一日。

ある素晴らしい夏の夜、長い間忘れられていたが魅力的なものを探して、私は箱の中の物を整理しました。 最後に一見したところ、もう少し必死でしたが、私はまだ面白いものを見つけました。 それは自転車用の中国の速度計でした。 もちろん、マイコンはありませんでした-驚くことではありません(子供の頃、私の好奇心のおかげで、調べたもののほとんどは収集されず、単に捨てられました)。 しかし、これが唯一の問題ではありませんでした-私は自転車を持っていません。 彼は兄に連れて行かれ、私自身はスケートボードに乗っています。 それで、あなた自身で何をすべきかというアイデアが生まれました!



カットの下にたくさんの写真。



コンポーネント



スケート


私はスケートボードでスタントを演じていないので、楽しみのためにクルーザーボードに乗ります。面白いのは、「どれくらい乗りましたか?」です。



クルーザーボードの写真




スマートウォッチ


新年には、これらの時計を中国から購入しました。



スマートウォッチの写真




これは、Z-Watchと呼ばれるSmartQスマートウォッチです。 それらは、古い(Z1)モデルと若い(Z1-Lite)モデルに分けられます。 違いは、若いモデルにはWi-fiモジュール、eMMCフラッシュメモリ512Mb(古い4Gb)、256Mb RAM(古い512Mb)がないことです。 この時計には、解像度240x240ピクセルの1.54インチTFT LCDスクリーン、周波数1.0GhzのIngenic JZ4775プロセッサ、Bluetooth 4.0 BLE、Wi-fi IEEE 802.11 b / g / n、加速度計、防水IP-X7(3 ATM)、Liバッテリーが搭載されています-300mAhのpoly、OS Android 4.4 KitKat(簡略化)。



Arduino Mini Pro


マイクロコントローラーArduino Pro Mini:



写真Arduino Pro Mini




手元にあるという理由だけで選ばれました。 ホイールの回転数をカウントします。



Bluetooth HC-06


時計と通信するBluetoothモジュール:



Bluetoothモジュールの写真






リードセンサー


中国の自転車用速度計のセンサー:



センサー写真






バッテリー


Samsungバッテリー3.7V、1000mAh:

バッテリー写真






組立



デバイスのスキーム:

スピードメーター回路




コメントは必要ないと思います。 もちろん、LEDはトランジスタを介して接続する必要があります-その後、より多くの光がありますが、これはそれほど重要ではありません。 ブレッドボードにプロトタイプをまとめました。 バッテリーを取り付けた両面テープの底部があります。 将来的にはそれぞれ自転車を手に入れることができるので、自転車のハンドルバーへのセンサーマウントを切断しませんでした:)

プロトタイプ写真








鞭毛を使用してサスペンションにリードスイッチ付きのセンサーを取り付けました。



スケートボードの底の写真




以下のLEDは、クロックからマイクロコントローラーへのデータ転送を確認するために取り付けられました。 夜のバックライトとして適しています。

ホイールに浅い穴を開けて、ネオジム磁石を固定しました(古いドライブから引き抜いた)。



磁石付きホイールの写真






ソフトウェア部



私はプログラミングが得意ではありませんが、これに関するアドバイスを喜んでいます!



マイクロコントローラー


volatile long cntr; boolean flip; boolean yes = false; int rev = 0; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); pinMode(12, INPUT); TCCR2A = 0; TCCR2B = 2; TCNT2 = 59; TIMSK2 |= (1 << TOIE2); } ISR(TIMER2_OVF_vect) { TCNT2 = 59;//55; cntr++; if(cntr>9999) { flip = true; cntr = 0; } } void loop() { if (flip) { Serial.println(String(rev)+';'); rev = 0; flip = false; } else { if (digitalRead(12) == HIGH) { if (yes) { rev++; yes = false; } } else yes = true; } if (Serial.available() > 0){ char command = Serial.read(); switch(command){ case '0': digitalWrite(13, LOW); break; case '1': digitalWrite(13, HIGH); break; } } }
      
      







プログラムの本質


タイマーがカチカチと音を立てている間、回転数がメインサイクルでカウントされ、クロックからのコマンド(ある場合)が処理されます。 1秒後に、コントローラーは回転数をクロックに送信します。 周波数(r / c)があります。



時計


コードはこの記事から引用され、少し追加されました。

コード
AndroidManifest.xml


 <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
      
      







FullscreenActivity.java


 package com.example.admin.speedometer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.UUID; import com.example.admin.speedometer.R; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import android.bluetooth.*; import android.content.Intent; public class FullscreenActivity extends Activity { private static final int REQUEST_ENABLE_BT = 1; final int ArduinoData = 1; final String LOG_TAG = "myLogs"; private BluetoothAdapter btAdapter = null; private BluetoothSocket btSocket = null; private StringBuilder sb = new StringBuilder(); private static String MacAddress = "20:13:05:07:01:97"; // MAC-   private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private ConnectedThred MyThred = null; public TextView spdtext, distext, fromarduino; public double Distance = 0; Button b1, b2; Handler h; /* Settings: */ private static double Radius = 3.0; //    private static double spdUnit = 3.6; // : 3.6  /, 1.0  /c @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fullscreen); btAdapter = BluetoothAdapter.getDefaultAdapter(); spdtext = (TextView) findViewById(R.id.textView1); distext = (TextView) findViewById(R.id.textView2); fromarduino = (TextView) findViewById(R.id.textView5); if (btAdapter != null){ if (btAdapter.isEnabled()){ //mytext.setText("Bluetooth .  ."); }else { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }else { MyError("Fatal Error", "Bluetooth "); } b1 = (Button) findViewById(R.id.button1); b2 = (Button) findViewById(R.id.button2); b1.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("1"); } }); b2.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("0"); } }); h = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case ArduinoData: byte[] readBuf = (byte[]) msg.obj; String strIncom = new String(readBuf, 0, msg.arg1); sb.append(strIncom); int endOfLineIndex = sb.indexOf("\r\n"); if (endOfLineIndex > 0) { String sbprint = sb.substring(0, endOfLineIndex); sb.delete(0, sb.length()); String value = ""; byte channel = 0; //   : 0;0;0; fromarduino.setText("Arduino: " + sbprint); for (int i = 0; i < sbprint.length(); i++) { if (sbprint.charAt(i) == ';') { if (!value.isEmpty()) { switch (channel) { case 0: double Dis = (Double.parseDouble(value) * (Radius * 6.28) ) / 100.0; double Speed = Dis * spdUnit; spdtext.setText(String.valueOf(Math.round(Speed))); Distance += Dis; distext.setText(String.valueOf(Math.round(Distance))); break; } } value = ""; channel++; } else value += sbprint.charAt(i); } } break; } }; }; } @Override public void onResume() { super.onResume(); BluetoothDevice device = btAdapter.getRemoteDevice(MacAddress); Log.d(LOG_TAG, "***  Device***"+device.getName()); try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); Log.d(LOG_TAG, "... ..."); } catch (IOException e) { MyError("Fatal Error", " onResume()    : " + e.getMessage() + "."); } btAdapter.cancelDiscovery(); Log.d(LOG_TAG, "***   ***"); Log.d(LOG_TAG, "***...***"); try { btSocket.connect(); Log.d(LOG_TAG, "***  ***"); } catch (IOException e) { try { btSocket.close(); } catch (IOException e2) { MyError("Fatal Error", " onResume()    " + e2.getMessage() + "."); } } MyThred = new ConnectedThred(btSocket); MyThred.start(); } @Override public void onPause() { super.onPause(); Log.d(LOG_TAG, "...In onPause()..."); if (MyThred.status_OutStrem() != null) { MyThred.cancel(); } try { btSocket.close(); } catch (IOException e2) { MyError("Fatal Error", " onPause()    " + e2.getMessage() + "."); } } private void MyError(String title, String message){ Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show(); finish(); } //     private class ConnectedThred extends Thread{ private final BluetoothSocket copyBtSocket; private final OutputStream OutStrem; private final InputStream InStrem; public ConnectedThred(BluetoothSocket socket){ copyBtSocket = socket; OutputStream tmpOut = null; InputStream tmpIn = null; try{ tmpOut = socket.getOutputStream(); tmpIn = socket.getInputStream(); } catch (IOException e){} OutStrem = tmpOut; InStrem = tmpIn; } public void run() { byte[] buffer = new byte[1024]; int bytes; while(true){ try{ bytes = InStrem.read(buffer); h.obtainMessage(ArduinoData, bytes, -1, buffer).sendToTarget(); }catch(IOException e){break;} } } public void sendData(String message) { byte[] msgBuffer = message.getBytes(); Log.d(LOG_TAG, "*** : " + message + "***" ); try { OutStrem.write(msgBuffer); } catch (IOException e) {} } public void cancel(){ try { copyBtSocket.close(); }catch(IOException e){} } public Object status_OutStrem(){ if (OutStrem == null){return null; }else{return OutStrem;} } } }
      
      









プログラムの本質


プログラムは、車輪速度に関するデータをマイクロコントローラーから受け取ります。 正しい情報を取得するには、ホイールの半径を測定する必要があります。プログラムはその円周を見つけ、速度と距離を計算します。 ホイールの半径と速度が表示される単位を調整する必要があります。

 /* Settings: */ private static double Radius = 3.0; //    private static double spdUnit = 3.6; // : 3.6  /, 1.0  /c
      
      





N-回転数;

lは円周です。

t-時間(1秒に1回カウントするため、この値は無視できます);

l = 2prは円周です。

S = V * t =(N * l)/ 100-1秒で移動した距離(メートルで表示);

 double Dis = (Double.parseDouble(value) * (Radius * 6.28)) / 100.0;
      
      





V = S / t = S * 3.6-速度(km / hで表される)。

 double Speed = Dis * spdUnit;
      
      





また、2つのボタンがあります。 オフ スケートボードの下部にあるLED。



おわりに


いくつかのエラーがありますが、全体的には結果に満足しています。 sychidzeの記事をありがとう!

ビデオ作品はもう少し後になるでしょう。



All Articles