pythonでFFTしてみた
便利な世の中になったもんだ。
参考にしたのは
org-technology.com
ism1000ch.hatenablog.com
など。
ソースは以下。
import numpy as np from scipy.fftpack import fft from scipy.fftpack import fftfreq from scipy.fftpack import fftshift import matplotlib.pyplot as plt import pandas as pd #データ数 N = 800 #サンプリング周期(sec) dt = 0.001 #周波数 f = 5.0 #時間軸 t = np.linspace(1,N,N) * dt - dt #時系列データ y = np.sin(2 * np.pi * f * t) #周波数軸(MATLAB等で言うfftshiftがかかっている) freq = fftfreq(N,dt) #FFT yf = fft(y) plt.figure(1) plt.xlabel("time(sec)") plt.ylabel("value(a.u.)") plt.plot(t,y) plt.figure(2) plt.xlabel("freq(Hz)") plt.ylabel("amplitude(a.u.)") plt.plot(freq,np.abs(yf)) #plt.plot(freq,np.real(yf)) #実部 #plt.plot(freq,np.imag(yf)) #虚部 print(np.real(yf)) plt.show() df = pd.DataFrame(freq) df.to_csv("freq.csv")
5Hzのsin波
FFT結果(power)
(C#)絶対に二重起動させない方法
毎回忘れるのでメモ。
この方法だと、絶対に二重起動しない。
Application.Run()がusingの中に入っているのがミソ。
[STAThread] static void Main() { using (Mutex mutex = new Mutex(false, "APP NAME")) { if (mutex.WaitOne(0, false) == false) { MessageBox.Show("二重起動はできません。", "APP NAME"); return; } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } }
(BLE)WindowsでKonashiのアナログ入力を読む
ようやくできたよ・・・。
Windows 10のノートPCで動作確認。他は知らない。
ハマったポイントは、
characteristic.ReadValueAsync()メソッドが、デフォルトでキャッシュした値を返していたこと。
BluetoothCacheMode enumeration - Windows app development
にあるように、引数をunchachedにしたら、ちゃんと読めた。
以下ソース。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; using Windows.Devices.Bluetooth; using Windows.Devices.Bluetooth.GenericAttributeProfile; using Windows.Devices.Enumeration; using System.Threading; using System.Threading.Tasks; using Windows.UI.Popups; namespace BreathMonitorKonashi { public sealed partial class MainPage : Page { private const string KONASHI_SERVICE = "229BFF00-03FB-40DA-98A7-B0DEF65C2D4B"; private const string KONASHI_AIO0_CHARACTERISTIC = "229B3008-03FB-40DA-98A7-B0DEF65C2D4B"; private GattDeviceService service; private GattCharacteristic characteristic; Timer timer; public MainPage() { this.InitializeComponent(); } private async void btnConnect_Click(object sender, RoutedEventArgs e) { //デバイスを検索 var selector = GattDeviceService.GetDeviceSelectorFromUuid(new Guid(KONASHI_SERVICE)); var deviceInfomations = await DeviceInformation.FindAllAsync(selector); var deviceInfomation = deviceInfomations.FirstOrDefault(); if (deviceInfomation != null) { //サービス取得 this.service = await GattDeviceService.FromIdAsync(deviceInfomation.Id); //キャラクタリスティック取得 var characteristics = this.service.GetCharacteristics(new Guid(KONASHI_AIO0_CHARACTERISTIC)); if (characteristics.Count > 0) { this.characteristic = characteristics.First(); var dialog = new MessageDialog("Connected to " + deviceInfomation.Name); await dialog.ShowAsync(); //ADC読み取りスレッド開始 TimerCallback timerDelegate = new TimerCallback(onTimer); timer = new Timer(timerDelegate, null, 0, 100); } } } private async void onTimer(object sender) { if (characteristic == null) { return ; } var result = await characteristic.ReadValueAsync(BluetoothCacheMode.Uncached); //キャッシュしてやがった! byte[] value = result.Value.ToArray(); int val = (value[0] << 8) + value[1]; //[0]番目に上位バイト、[1]番目に下位バイト System.Diagnostics.Debug.WriteLine(val); lastVal = val; } } }
(UWP)プロジェクト作成でコケるときのおまじない
いろいろ調べたけど、おまじないで逃げることにする。
プロジェクト作成したら、パッケージマネージャで、
PM> Install-Package Microsoft.NETCore.UniversalWindowsPlatform
を実行。
(Java,Android)twitter4jで最新のユーザータイムライン1つだけ取得する
題記の通り。
これで、5秒に1回の頻度(?)で監視できる。
Paging paging = new Paging(); paging.setCount(1); //1個に指定 List<twitter4j.Status> statuses =twitter.getUserTimeline("ユーザ名", paging); final Status status = statuses.get(0); Log.d("twitter4j", status.getUser().getScreenName() + " - " + status.getText());
【HTML】mmenuで右からスライドメニューを出す【javascript】
ちゃんとリファレンス読みましょう>俺
デモを見てたら、scriptはこう書く模様。
jQuery(document).ready(function( $ ) { $("#menu").mmenu({ "offCanvas": { "position": "right" } }); });
(ToCoStick)Node.jsでシリアル通信してブラウザでグラフ表示(ccchart)
Node.jsのお勉強が必要になり、ひと段落したからメモ。
TWE-Liteから33msecごとにデータが送られてくると想定。
アナログ入力1の値を読み取り、wsモジュールを使ってccchartに送る。
以下、ソース。
index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=480"> <title>TWE-Lite Monitor by ccchart</title> </head> <body> <script src="ccchart-min.js" charset="utf-8"></script> <canvas id="hoge"></canvas> <script> var chartdata = { "config": { "width": (window.innerWidth-60) , "height": (window.innerHeight-60)/1.2, "lineWidth": 2, "xScaleSkip": 33, "useVal": "no", "bg": "#000", "colorSet": ["#00FF00",], "maxY": 2000, "minY": 0, "maxWsColLen": 333 }, "data": [ ["時間"], ["電圧"] ] }; ccchart .init('hoge', chartdata) .ws('ws://127.0.0.1:3001') .on('message', ccchart.wscase.someColsAtATime); </script> </body> </html>
ccchartTest.js
var WsServer = require('ws').Server; var ws = new WsServer({port : 3001}); var express = require('express'); var serialport = require('serialport'); const ARRAY_NUM = 333; var dataArr = new Array(ARRAY_NUM); var time = 0; //in msec clearArray(); function clearArray(){ var now = new Date(); var hour = ZeroFormat(now.getHours(),2); var min = ZeroFormat(now.getMinutes(),2); var sec = ZeroFormat(now.getSeconds(),2); var nowStr = hour + ":" + min + ":" + sec; for(i = 0;i < ARRAY_NUM;i++){ dataArr.push([[nowStr],[1000.0]]); } //console.log(dataArr); } broadcast(); function broadcast(volt){ var tid = setInterval( function(){ ws.clients.forEach(function(client){ client.send(JSON.stringify(dataArr)); // console.log(dataArr); }); }, 100); //100msec毎に送信 } var portName = 'COM3'; var sp = new serialport.SerialPort(portName,{ baudRate: 115200, dataBits: 8, parity: 'none', stopBits: 1, flowControl: false, //parser: '\n'//serialport.parsers.readLine("\n"); }); sp.on('open', function(){ console.log('serial port open'); }) sp.on('data',function(input){ var inBuffer = new Buffer(input, 'ascii'); if(inBuffer.length < 49){ return; } var inStr = inBuffer.toString('ascii',37,39); var volt = 1.0 * (parseInt(inStr,16) * 16); //10進に変換,16倍して電圧にも変換,1.0倍してfloatに変換 // console.log(volt); addData(volt); }); function addData(volt){ var now = new Date(); var hour = ZeroFormat(now.getHours(),2); var min = ZeroFormat(now.getMinutes(),2); var sec = ZeroFormat(now.getSeconds(),2); var nowStr = hour + ":" + min + ":" + sec; dataArr.shift(); //最初の要素を取り除いて、 dataArr.push([[nowStr],[volt]]); //push } /** * [関数名] ZeroFormat * [機 能] ゼロ埋め * [説 明] 数値が指定した桁数になるまで数値の先頭をゼロで埋める * * @param integer num 数値 * @param integer max 桁数 * @return integer tmpS ゼロ埋め後の数値 */ function ZeroFormat(num,max){ var tmp=""+num; while(tmp.length<max){ tmp="0"+tmp; } return tmp; }
ZeroFormat関数は
http://phpjavascriptroom.com/exp.php?f=include/js/formcheck/zero2.inc&ttl=%E6%95%B0%E5%80%A4%E3%81%AE%E5%85%88%E9%A0%AD%E3%82%92%E3%82%BC%E3%83%AD%E3%81%A7%E5%9F%8B%E3%82%81%E3%82%8B
を使わせて頂きました。