Arduinoを使用した多数のオブジェクト(IPTVチャネルなど)の視覚的な監視

この記事では、長年のアイデアであるiptvチャンネルの状態を視覚的に表示する方法をどのように実現したかを説明します。 一般的に、最初は監視がすべてでした-たとえば、都市の地図、LEDが(機器が配置されている場所に)配置され、この地図を見れば、どこで何が起こったのかをすぐにはっきりと確認できます。

しかし、私の場合、それはIPTVチャンネルに関するものです。



これらのチャネルの多くは160個近くありますが、これはサービスチャネルをカウントしません。たとえば、連邦チャネルは多重化されます(たとえば、TNTチャネルは都市の異なる部分にある2つの受信機から取得されます(もちろん、理想的には別の都市から取得したい)、プライベートマルチキャストストリームはマルチプレクサに組み込まれ、マルチプレクサはすでに1つのパブリックマルチキャストを発行し、事故が発生した場合、チャネルの1つが自動的に予約に切り替わります。



当然、ソフトウェアによる監視を調整しました。 彼は、たとえば、すべてのチャンネルを実行するスクリプトの完全な複合体を構築しました-それらにサブスクライブし、ストリームのエラーをチェックし、チャンネルエンコーディングをチェックし、カムモジュールをジャークして修正を試みます(telnet、snmpを使用)、レシーバーを再起動するのは簡単ですそれから来る失敗したチャンネルの数は半分以上です。もちろん、すべての重要なイベントについて私は気づきます。 これに加えて、ネットワーク全体の統計情報は、stb-shek、スイッチ、ユーザーが使用しているファームウェアの種類、コンソールの種類、ほとんどの人が視聴している特定のプログラムからも収集されます(非常に興味深い事実)。



明確にするために、モザイクの形でチャネルを実行するプログラム、または特定の

画面上のチャンネルの一部(1つの画面上の160チャンネルすべてが収まらないことを理解していますが、良好なプロセス/ビデオカード/ネットワークカードを備えたコンピューター上の4x6 = 24 SDチャンネルは非常に現実的です)。



一般に、プログラム的には、これはすべてすでに存在しますが、コンピューターがなくて、LEDの形で-それはありません...

そして、Arduinoに会いました。

あなたはおそらくこれが何につながったのか理解しているでしょう。



私ははんだごてとは友達ではなかったので(そして今では強くありませんが、すでにある程度進歩することを望んでいます)、回路などにまったく友好的ではありませんでした。 -最初は(そして今も)私にとっては難しいことでしたが、それが目標でした-新しいことを学び、以前は知らなかったものを知ることです。 シフトレジスタ、懐中電灯、「動的表示」などを使用してLEDのマトリックス全体を制御する方法などについて学んだプロセスについては詳しく説明しません。 最後に何が起こったのかをお伝えします(そして、私はそれを行いました!)。



クリック可能



そこで、16x10 LEDのマトリックスを完成したプロトタイプボードにはんだ付けし、4つのシフトレジスタ74HC595を介して接続しました。 彼女のためにenc28j60でarduinoとethershieldによって使用されます。

このようになった(写真はクリック可能)



クリック可能



クリック可能



クリック可能



バージョン0.22およびethershieldライブラリバージョン1.1を使用した開発環境用のコード。

あなたが突然繰り返したい場合、私は確かに新しいものがあることを知っている瞬間に-あなたは適応する必要があるかもしれません



 #include "etherShield.h" static uint8_t mymac[6] = {0x00,0x80,0x48,0x2d,0xf7,0x25}; //  mac-  static uint8_t myip[4] = {10,20,30,40}; // ip- 10.20.30.40 #define MYPORT 5555 #define BUFFER_SIZE 500 static uint8_t buf[BUFFER_SIZE+1]; static char number[7]; const byte clockPin = 7; // const byte latchPin = 8; //         const byte dataPin = 9; // const byte NumRegs = 4; //    const byte NumCols=10; const byte NumRows=16; //      -       , //       //    4 ,       , //   //     ()   1  32 //     26  (10+16) -      byte Col_bits[NumCols] = {3,5,7,11,13,15,19,21,23,27}; //         //    , .. 1-  //    3    .. byte Row_bits[NumRows] = {32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2}; //      //      byte Regs[NumRegs]; int reg_n, bit_n, in_r, in_c; // , . //       2! ;) // -   byte matrix[NumRows][NumCols]={{1,0,1,0,0,0,1,1,1,1}, {1,0,1,0,0,0,0,0,0,1}, {1,0,1,0,0,0,0,0,0,1}, {1,0,1,0,0,0,0,0,1,0}, {1,0,1,0,0,0,0,0,1,0}, {1,0,1,1,0,0,0,0,1,0}, {1,0,1,0,1,0,0,1,0,0}, {1,0,1,0,1,0,0,1,0,0}, {1,0,1,0,1,0,0,1,0,0}, {1,0,1,0,1,0,1,0,0,0}, {1,0,1,0,1,0,1,0,0,0}, {1,0,1,1,0,0,1,1,1,1}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}}; EtherShield es=EtherShield(); void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); es.ES_enc28j60Init(mymac); //   es.ES_init_ip_arp_udp_tcp(mymac,myip, MYPORT); //   } void loop() { uint16_t plen, dat_p, ptr; while(1) { burn_matrix(); //          //        ( ).    //       ,     //     -      //   - read packet, handle ping and wait for a tcp packet: dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf)); /* dat_p will be unequal to zero if there is a valid request */ if(dat_p == 0) { // no request continue; } //             :) //        "IbZ " if (strncmp("IbZ ",(char *)&(buf[dat_p]),4)==0) { //   4-       ptr = dat_p+4; for(in_r=0; in_r < NumRows; in_r++) { for(in_c=0; in_c < NumCols; in_c++) { matrix[in_r][in_c] = 0; //    ( ,    ;) ) } } //    -   -   //   ,   - 0 while(buf[ptr] != 0) { in_r = (buf[ptr]-1) % 16; in_c = (buf[ptr]-1) / 16; matrix[in_r][in_c] = 1; //     ptr++; } } } } void burn_matrix() { //     -  1- ,  , //  2- ,       10-  for(int c = 0; c < NumCols; c++) { for(int i = 0; i < NumRegs; i++) { Regs[i]=255; } reg_n = (Col_bits[c]-1) / 8; bit_n = (Col_bits[c]-1) % 8; bitWrite(Regs[reg_n], bit_n, 0); for(int r = 0; r < NumRows; r++) { reg_n = (Row_bits[r]-1) / 8; bit_n = (Row_bits[r]-1) % 8; bitWrite(Regs[reg_n], bit_n, matrix[r][c]); } registerWrite(); delay(1); } } //      -     void registerWrite() { digitalWrite(latchPin, LOW); for(int cur_reg = NumRegs-1; cur_reg >= 0; cur_reg-- ) { shiftOut(dataPin, clockPin, MSBFIRST, Regs[cur_reg]); } digitalWrite(latchPin, HIGH); } 
      





#include "etherShield.h" static uint8_t mymac[6] = {0x00,0x80,0x48,0x2d,0xf7,0x25}; // mac- static uint8_t myip[4] = {10,20,30,40}; // ip- 10.20.30.40 #define MYPORT 5555 #define BUFFER_SIZE 500 static uint8_t buf[BUFFER_SIZE+1]; static char number[7]; const byte clockPin = 7; // const byte latchPin = 8; // const byte dataPin = 9; // const byte NumRegs = 4; // const byte NumCols=10; const byte NumRows=16; // - , // // 4 , , // // () 1 32 // 26 (10+16) - byte Col_bits[NumCols] = {3,5,7,11,13,15,19,21,23,27}; // // , .. 1- // 3 .. byte Row_bits[NumRows] = {32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2}; // // byte Regs[NumRegs]; int reg_n, bit_n, in_r, in_c; // , . // 2! ;) // - byte matrix[NumRows][NumCols]={{1,0,1,0,0,0,1,1,1,1}, {1,0,1,0,0,0,0,0,0,1}, {1,0,1,0,0,0,0,0,0,1}, {1,0,1,0,0,0,0,0,1,0}, {1,0,1,0,0,0,0,0,1,0}, {1,0,1,1,0,0,0,0,1,0}, {1,0,1,0,1,0,0,1,0,0}, {1,0,1,0,1,0,0,1,0,0}, {1,0,1,0,1,0,0,1,0,0}, {1,0,1,0,1,0,1,0,0,0}, {1,0,1,0,1,0,1,0,0,0}, {1,0,1,1,0,0,1,1,1,1}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}}; EtherShield es=EtherShield(); void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); es.ES_enc28j60Init(mymac); // es.ES_init_ip_arp_udp_tcp(mymac,myip, MYPORT); // } void loop() { uint16_t plen, dat_p, ptr; while(1) { burn_matrix(); // // ( ). // , // - // - read packet, handle ping and wait for a tcp packet: dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf)); /* dat_p will be unequal to zero if there is a valid request */ if(dat_p == 0) { // no request continue; } // :) // "IbZ " if (strncmp("IbZ ",(char *)&(buf[dat_p]),4)==0) { // 4- ptr = dat_p+4; for(in_r=0; in_r < NumRows; in_r++) { for(in_c=0; in_c < NumCols; in_c++) { matrix[in_r][in_c] = 0; // ( , ;) ) } } // - - // , - 0 while(buf[ptr] != 0) { in_r = (buf[ptr]-1) % 16; in_c = (buf[ptr]-1) / 16; matrix[in_r][in_c] = 1; // ptr++; } } } } void burn_matrix() { // - 1- , , // 2- , 10- for(int c = 0; c < NumCols; c++) { for(int i = 0; i < NumRegs; i++) { Regs[i]=255; } reg_n = (Col_bits[c]-1) / 8; bit_n = (Col_bits[c]-1) % 8; bitWrite(Regs[reg_n], bit_n, 0); for(int r = 0; r < NumRows; r++) { reg_n = (Row_bits[r]-1) / 8; bit_n = (Row_bits[r]-1) % 8; bitWrite(Regs[reg_n], bit_n, matrix[r][c]); } registerWrite(); delay(1); } } // - void registerWrite() { digitalWrite(latchPin, LOW); for(int cur_reg = NumRegs-1; cur_reg >= 0; cur_reg-- ) { shiftOut(dataPin, clockPin, MSBFIRST, Regs[cur_reg]); } digitalWrite(latchPin, HIGH); }









アルゴリズムは単純です。チャネルが機能しなくなった場合-すぐに表示されます-LEDが点灯し始め、LEDは消えません。

チャンネルがチェックされると、LEDが点灯します;すべてが正常であれば、LEDは消灯します。 スクリプトがチャネルをチェックする様子を見ることができます。 監視サーバー上で30分に1回実行され(チャネルごとに8秒以上かかります)、プライベートフェデラルサーバーは個別にチェックされ、ここには表示されません-計画内にあります(残念ながら真実はおそらく実行不可能です:()多数のLEDのマトリックスを作成し、複数のサーバーを起動します監視(すべてのチャネルが5〜10分ごとにチェックされるようにプロセスを並列化します)。



ここに短いビデオがあります:







まあ、慣習として、使用される主な材料のおおよそのコスト(基本的にはすべてがeBay /中国の店で購入されました):

ブレッドボードプロトタイプPCBプリント基板18 x 30 〜4ドル
160個の緑色の3mm LED 5ドル未満が見つかります
Arduino 〜16ドル
Arduino Duemilanove / Uno用ENC28J60イーサネットシールド 〜16ドル
4つのレジスタ74HC595 〜3ドル
合計で 〜$ 45-50



All Articles