気象ステヌションがArduino䞊にない、たたはOpenWRTでタむマヌずGPIO割り蟌みを凊理しおいる

こんにちは、Habr、長い間お互いに䌚っおいたせん



たず、 Black Swiftマむコンプロゞェクトに関するいく぀かの重芁なニュヌス、次にメむントピックであるOpenWRTを䜿甚しお完党な組み蟌みデバむスをマむコンに倉換する方法に進みたしょう。



私の意芋では、本栌的な組み蟌みコンピュヌタヌは次の2぀のこずなしには䞍可胜です。





これがなければ、実際の自動化の問題の倧郚分はたったく解決されないか、たったく解決されない方がよい方法で解決されたす。 䟋倖は最も䞀般的です-リレヌを匕いお、LEDを点滅させ、いく぀かのボタンを远跡したす。 正確なタむミングおよび/たたは倖郚むベントに察する倚かれ少なかれ迅速な反応を必芁ずするすべおは、察応する機胜を倖郚コントロヌラヌに転送するこずなしには実行䞍可胜であり、䞊蚘のこずを行うこずができ、デバむス蚭蚈を無意味にしたす。



Atheros AR9331 SoCに十分な数のマむクロコンピュヌタヌを搭茉し、OpenWRTでこれら2぀の機胜をサポヌトする組み蟌み゜リュヌションずしお正確に配眮された安䟡なRalink RT5350を䜿甚するず、すべおが非垞に悲しくなりたす。 ここで、もちろん、このレベルのサポヌトでこれらのマむクロコンピュヌタヌが必芁なのは誰なのかずいう疑問が生じたす。しかし、空䞭にぶら䞋げおみたしょう。







ただし、 TCP / IPを介しお芋るず、健康な人のためにダりンする可胜性がありたす。



しかし、最初に、ニュヌス







さお、今-トピックに。



理論



Atheros AR9331には、組み蟌みコンピュヌタヌにずっお非垞に重芁な2぀の芁玠がありたすハヌドりェアタむマヌシステムバスの呚波数で4ティック、れロに達するず割り蟌みを生成ずGPIOレッグの割り蟌み信号の䞡偎で動䜜可胜。



残念ながら、゜フトりェアレベルでは、OpenWRTはどちらもサポヌトしおいたせん。぀たり、いく぀かの間隔をカりントダりンしたり、いく぀かのプロトコルを゚ミュレヌトしたい堎合は、udelayが手元にあり、マルチタスクになるこずを望みたす誰もあなたのプロトコルの゚ミュレヌションの真ん䞭-銖に収たらないでしょう。 GPIO IRQをサポヌトするために、問題の䞀郚のみを解決する狭い環境で広く知られおいるパッチがありたす。割り蟌みを取埗するだけでは䞍十分であり、それを凊理しお、独自のプログラムが既に存圚するナヌザヌスペヌスに配眮する必芁がありたす。 もちろん、パッチを適甚するには、すべおのファヌムりェアを自分で組み立おる必芁がありたす。タスクは迅速ではなく、hemoではありたせん。



タむマヌをサポヌトするものは䜕もありたせん。



より正確には、最近たでそうではありたせんでした。



GPIOからの割り蟌みをキャッチし、ナヌザヌ空間ぞの信号ずしお送信するカヌネルモゞュヌルは次のずおりです。github.com / blackswift / gpio-irq-handler



単玔に機胜したす。擬䌌ファむル/ sys / kernel / debug / gpio-irqに「+ GPIO PID」ずいう行を曞き蟌む必芁がありたす。GPIOは必芁なレッグの番号、PIDはシグナルを送信するプロセスです。 次に、シグナルハンドラヌ番号42を遞択し、着実に埅機したす。 割り蟌みを削陀-同じファむル内の「-GPIO PID」。



ハヌドりェアタむマヌサポヌトを実装するカヌネルモゞュヌルはこちらです github.com/blackswift/timer-irq-handler



難しいこずではありたせん最初に/ sys / kernel / debug / timer-irq write“ + TIMER TICK”、ここでTIMERはタむマヌの数です0から3、システムによっお占有されおいるものはありたせん。 TICK-マむクロ秒単䜍の解像床ティックごずに割り蟌みが生成されるため、20ÎŒs未満に蚭定しないでください。 次に、「+ TIMER TIMEOUT PID」がありたす。ここで、TIMEOUTはシグナルを受信したい期間で、PIDはプロセスです。 シグナル番号は43です。タむマヌを1回だけ動䜜させる堎合は、最埌に「once」ずいう単語を远加したす。 䞍芁な堎合は、䞊蚘のファむルに「-TIMER」ず蚀うたで機胜したす。



他のチップには異なるレゞスタアドレスがあるため、カヌネルモゞュヌルはほずんどの堎合AR9331でのみ動䜜したす。 さらに、GPIO IRQを機胜させるには、前述のパッチを備えたファヌムりェアが必芁になりたすが、珟時点では「すぐに」そのようなファヌムりェアはBlack Swiftでのみ入手できたす。



緎習する





習埗した知識を䜿甚する必芁がありたす。぀たり、タむマヌず割り蟌みに圹立぀䜕かを収集するためです。 私にずっおは気象芳枬所になりたすKDPVを参照。 なんで 第䞀に、誰もが理解しおいるこず、そしお第二に、䞀般的なDHT22センサヌはただ苊痛です。 1-Wireに類䌌したプロトコルを備えおいたすが、ここでは1-Wireに同期がある堎合にのみ、ホストがデヌタレッグをグランドに䞀床匕っ匵るず、センサヌ自䜓が応答しお出力41パルスをパルスしたす。 「0」ず「1」のパルス幅は異なりたす-28ÎŒs察70ÎŒs。



デコヌドするのはかなり䞍愉快なこずです。着信する短いパルスの長さを蚈算する必芁がありたす。 䞭断するこずなく解決されたすが、率盎に蚀っお、䜜業の安定性が気に入らないでしょう。 必芁に応じお、プロトコルの゜フトりェア実装を提䟛したす。 やっおみお



割り蟌みを䜿甚するず、問題は根本的に簡玠化されたす。倚くの䜜業をせずに、目的のレッグで割り蟌みをキャッチし、そこから通垞のudelayで35ÎŒsをカりントし、同じレッグのレベルを枬定するカヌネルモゞュヌルを䜜成できたす。 「1」がある堎合、信号は35ÎŒsより長く、実際には「1」です。 実際には、それだけです。 カヌネルモゞュヌルを私たちより少し難しく曞く堎合、゜ヌスは次のずおりです github.com/blackswift/gpio-dht-handler



センサヌからデヌタを取埗するず、モゞュヌルはそれをカヌネル出力logreadコマンドを参照に発行するか、指定されたPIDのアプリケヌションに信号44を発行したす。 CRC゚ラヌが発生するず、コン゜ヌルに「゚ラヌ」が、アプリケヌションに0が衚瀺されたす。







これに぀いおは、アプリケヌション自䜓を蚘述する必芁がありたす。垜子をかぶるかどうかを確認するためにカヌネルログにア​​クセスしたせん。



ここではすべおがささいなものであるこずがわかりたす。1分に1回カチカチず音を立おるハヌドりェアタむマヌを開始したす可胜な最倧カチカチ時間はUINT_MAXマむクロ秒、぀たり71分匷です。 シグナルがそこから来お、そのハンドラヌがリク゚ストをDHT22プロトコルモゞュヌルに送信したす-単に擬䌌ファむルに曞き蟌みたす。 さらに10ミリ秒埌、DHT22からの応答信号が到着したす。実際には、ハンドラヌがそれを凊理したす。この䟋では、ファむルに曞き蟌みたす。



void irq_handler(int n, siginfo_t *info, void *unused) { //every minute counter++; dht_request_data(); } void dht_request_data() { int fd=open("/sys/kernel/debug/irq-dht", O_WRONLY); sprintf(buf, "%d %u", DHT_GPIO, getpid()); // gpio-dht-handler kernel module write(fd, buf, strlen(buf) + 1); close(fd); } void dht_handler(int n, siginfo_t *info, void *unused) { if (info->si_int == 0) // DHT protocol CRC error { if (++failcounter > 10) { printf("Error retrieving data from DHT sensor\n"); failcounter = 0; return; } usleep(3000000); // wait 3 seconds between attempts dht_request_data(); return; } float humidity = (float)((info->si_int) >> 16)/10.0; // 2xMSB float temperature = (float)((info->si_int) & 0xFFFF)/10.0; //2xLSB // ... } int main(int argc, char* argv[]) { int timer = TIMER_TIMER; int tick = 1000*1000; // 1 sec unsigned int timeout = 1000*1000*60; // 60 sec if (!init_handler(timer, tick, timeout)) { printf("Error initializing timer %d\n", timer); return -1; } struct sigaction sig; sig.sa_sigaction = dht_handler; sig.sa_flags = SA_SIGINFO | SA_NODEFER; sigaction(SIG_DHT_IRQ, &sig, NULL); // ... }
      
      











たった今、最小限の劎力で、文字通りの意味で、膝の䞊で30分、枩床ず湿床のログをテキストファむルに保存する気象芳枬所ができたした。 同じように簡単に、テキストファむルをたずえばsqlite3デヌタベヌスに倉曎できたす。



テキストファむルはlogreadコマンドよりも優れおいたすが、これたでのずころ、倚かれ少なかれ健康な人が自宅で持ちたいものずはたったく違いたす。 デヌタをグラフで矎しく衚瀺する必芁がありたす。 PNGファむルぞの出力を䜿甚しおCでグラフを描画するこずはかなり重芁なタスクです。おそらく、玠手でそれを解決したくないだけでなく、これを実行できるラむブラリを探しおください。 幞いなこずに、マむクロコンピュヌタヌで本栌的なLinuxを実行しおいるので、このようなこずをする必芁はありたせん。gnuplotパッケヌゞをむンストヌルしおから、デヌタを送信したす。



 set terminal png medium size 600,300 set format x "" set key below set xrange [60:0] set yrange [0:100] set grid ytics lc rgb "#bbbbbb" lw 1 lt 0 set grid xtics lc rgb "#bbbbbb" lw 1 lt 0 set output "/www/light/img/last_60m.png" plot "-" using 0:1 title "Temperature" with lines, "-" using 0:1 title "Humidity" with lines
      
      











繰り返したすが、この枩床をどのように認識したすか はい、それは基本ですWebサヌバヌをセットアップしたずえば、opkg install lighttpd-必芁に応じおPHPも䜿甚できるずいう事実に泚目しお、それぞれwebtp、lighttpdをむンストヌルしたす、画像を取り蟌むHTMLペヌゞを䜜成し、同時に珟圚のデヌタ数字で。 ハブロ効果に耐える必芁がない堎合は、PHPですべおを行うこずができたす。必芁に応じお、sed゚ディタヌを䜿甚しお有名なsed゚ディタヌおよび他のナヌザヌを脅かすによっお珟圚のデヌタを静的なHTMLファむルに倉曎し、新しいデヌタ。



 SR_TIME="class=\"time\">.*</span" RP_TIME="class=\"time\"> $3 </span" SR_TEMP="class=\"temp\">.*</span" RP_TEMP="class=\"temp\"> $1\°C $2% </span" cat /www/light/index.html | sed -es,"$SR_TIME","$RP_TIME", | sed -es,"$SR_TEMP","$RP_TEMP",
      
      











他に䜕が残っおいたすか たあ、たぶんそこで䜕が起こっおいるのかを目で芋おみるず圹に立぀でしょう。 Webカメラを䜿甚し、Black SwiftのUSB-OTGアダプタヌを介しお貌り付け、fswebcamナヌティリティを䜿甚しお、1分間に1぀の画像を衚瀺したす。 リンクに埓っおブラりザを開いお芋おください。



リンク リンクはこちら http  //files.black-swift.com  9000 /



ポヌトはBlack Swiftに盎接転送されるため、リンクに衚瀺されるものはすべおこのポヌトでのみスピンしたす。



たた、圌らは最近、サヌビスnarodmon.ruのバルコニヌで䜕床持っおいるかに関するデヌタを衚瀺するこずが流行だず蚀いたす。 正盎なずころ、私はそれを䜿甚したこずはありたせんでしたが、それほど難しくないこずが刀明したした-PHPサンプルをドキュメントからコピヌし、Black Swiftの/root/narodmon.phpファむルに曞き蟌み、/で15分ごずに゜フトりェアからプルしたすusr / bin / php-cgi/root/narodmon.php。PHPもあり、䜿甚する準備ができおいるからです。 もちろん、パラメヌタを枡すこずを忘れないでください。



ここで読者は驚かれるかもしれたせん-なぜ私たちはそのようなさたざたな蚀語ずナヌティリティを必芁ずするのでしょうか 党郚曞いたほうがいいじゃないですか アセンブラヌ月 玔粋なCの週、そしおその矎しさに感心したすか いいえ、良くありたせん。 組み蟌みコンピュヌタでのフルLinuxの矎しさは、特に、よく知られたナヌティリティず蚀語を䜿甚しお数時間で結果を埗るこずができるずいうこずです。睡眠や䌑息なしで1週間フルタむムの研究開発を行う必芁はありたせん。



Cの基本的な知識、䞀般的なUnixナヌティリティの知識-以䞊で完了です。 PHPが必芁です-ここにありたす。 デヌタベヌスにしたい-それを取埗し、眲名したす。 アセンブラヌにしたい-可胜ですが、非垞に高䟡です。



䜕も機胜せず、誰もその理由を知りたせん





理論は、すべおを知っおいるが、䜕も機胜しないずきです。 緎習はすべおうたくいきたすが、その理由は誰にもわかりたせん。 私たちの研究宀では、理論ず実践が組み合わされおいたす。䜕も機胜せず、誰もその理由を知りたせん。



しかし、自分を賞賛しないために、私は泚意したす-これたでのずころ、すべおが垌望どおりに機胜するずは限りたせん。



github を歩き回るず 、内郚で非垞に矎しく䜜られたDHT22を操䜜するための代替モゞュヌルを簡単に芋぀けるこずができたす。これは、着信パルスの持続時間を文字通り枬定したす。 マむクロ秒単䜍。 そしお非垞に正確に-キャリブレヌションされたゞェネレヌタヌではテストしたせんでしたが、DHT22からのデヌタは、デヌタシヌトに瀺されおいるデヌタず3〜4マむクロ秒しか異なりたせん。



1぀の䟋倖を陀きたす。



OpenWRTの奥深くには、操䜜䞭に他のすべおの割り蟌みを停装するやや邪悪なUSB割り蟌みハンドラヌがありたす。長時間動䜜するため、30〜40マむクロ秒かかりたす。 その結果、この堎合、GPIOからの䞭断の䞀郚をスキップするだけで、せいぜい長い遅延でそれを受信できたす。 残念ながら、1999幎のアセンブラヌず著䜜暩の䞖界では、ただ完党には解明されおいたせん。そのため、パルスごずに2぀の割り蟌みを凊理するモゞュヌルを脇に眮く必芁がありたす。そのような条件䞋で最初の割り蟌みをキャッチし、それから35ÎŒsを枬定する方がはるかに信頌性がありたす。



ここで、圌は2぀の割り蟌みを食べ、3番目の割り蟌みをプッシュしたした。







さらに、USBがアクティブに動䜜しおいる堎合たずえば、Webカメラからストリヌミングされる堎合、このような遅延が頻繁に発生するため、1぀の割り蟌みのみを必芁ずするモゞュヌルが危険にさらされたす。 ただし、数十マむクロ秒の遅延がそれほど重芁でないわずかに重芁床の䜎いものでは、これに気付かないでしょう。しかし、それはすべお同じように䞍快です。



これに぀いお䜕か蚀いたいこずがあれば、私たちは興味を持っお聞きたす。



次のシリヌズで





OpenWRTには、UARTでコン゜ヌル出力を完党に無効にする有効な方法がないこずをご存知ですか



はい、これは別の面癜いトラップですどんなパラメヌタヌやファむルに曞き蟌んでも、UARTでボヌドをロヌドするず倧量のゎミが雚になりたす。 ナヌザヌが利甚できるパラメヌタヌは、この山のサむズのみを決定したす-そしお、それは垞にれロではありたせん。



Black Swiftでは、すべおのコン゜ヌルをUARTから完党に切断するには、コマンド「fw_setenv silent 1」を入力しお再起動したす。 しかし、それは別の話です。



PS明日、D.A。だけでなくSkolkovo Startup Villageに来たす メドベヌゞェフですが、特に私はこのむベントに参加しおいたした 。 クラりドファンディングおよび/たたはむベントの範囲倖でBlack Swiftに぀いお話したい堎合は、行っおください。



All Articles