從零開始使用Arduino自定義物聯(lián)網(wǎng)硬件

從面包板到制造開始你的開源物聯(lián)網(wǎng)設(shè)備的開發(fā)之旅

[站外圖片上傳中...(image-a8f04d-1556494524948)]

最近,我想為創(chuàng)客創(chuàng)建一個(gè)基于Arduino的低功耗物聯(lián)網(wǎng)(IoT)設(shè)備,內(nèi)置傳感器可用于將傳感器數(shù)據(jù)從任何位置傳送到云端,并可能控制連接設(shè)備,如恒溫器,燈,門鎖和其他家庭自動(dòng)化產(chǎn)品。在此過(guò)程中,我了解到創(chuàng)建一個(gè)新的IoT設(shè)備,從構(gòu)思到原型再到最終產(chǎn)品,并不像我想象的那么簡(jiǎn)單,并且沒(méi)有“隨時(shí)可用”的開發(fā)設(shè)備。然而,通過(guò)弄清楚如何做到這一點(diǎn),我創(chuàng)建了一個(gè)名為Siguino的新產(chǎn)品 ,一個(gè)開源的物聯(lián)網(wǎng)電路板,我希望這將使其他人更容易,更快地創(chuàng)建他們自己的物聯(lián)網(wǎng)產(chǎn)品。

Siguino基于Arduino Pro Mini的低功耗版本 ,具有板載傳感器和天線,并使用單個(gè)電池供電。它還利用了Sigfox(譯者注:Sigfox是一種采用超窄帶技術(shù),長(zhǎng)距離、低功耗、低傳輸速率的LPWAN技術(shù),主要應(yīng)用于低功耗、低數(shù)據(jù)量的物聯(lián)網(wǎng)或M2M連接方案。),一種用于將物聯(lián)網(wǎng)設(shè)備連接到云端的低功耗廣域網(wǎng)。

本文描述了從一個(gè)非常凌亂的面包板(但仍在工作)原型到一個(gè)最終的、定制設(shè)計(jì)的印刷電路板(PCB)的各個(gè)階段,其他人有望使用這些電路板。

[站外圖片上傳中...(image-593686-1556494524948)]

1.面包板

和眾多優(yōu)秀的創(chuàng)客項(xiàng)目一樣,我從一個(gè)概念電路開始。這涉及識(shí)別您希望設(shè)備具有的功能以及您將使用的組件。我想要我的設(shè)備:

  • 低功耗并基于Arduino(例如,使用ATmega328P芯片的Arduino Pro Mini )

  • 包括一個(gè)Sigfox芯片,以便它可以通過(guò)Sigfox網(wǎng)絡(luò)發(fā)送消息。我選擇WiSOL SFMR10芯片有兩個(gè)原因:

    • 它是一個(gè)只發(fā)送而接收的芯片,我沒(méi)有選擇雙向通信

    • 有一個(gè)DevKit 可用(對(duì)于面包板和原型設(shè)計(jì)非常有用)

  • 有四個(gè)基本傳感器:

    • 溫度(SparkFun DS18B20)用于連接的恒溫器

    • 用于連接燈的光電平(標(biāo)準(zhǔn)光電池)

    • 用于門打開/關(guān)閉的磁性檢測(cè)“霍爾效應(yīng)”,例如門是打開還是打開(DigiKey AH9246-W-7

    • 用于設(shè)備安全的運(yùn)動(dòng)檢測(cè)、跌倒檢測(cè)、周邊運(yùn)動(dòng)檢測(cè)等等。我試驗(yàn)了行程開關(guān)、水銀開關(guān)等,但我認(rèn)為加速度計(jì)(Adafruit LIS3DH)是創(chuàng)客的最佳選擇,因?yàn)樗_啟了電路板的固有可能性。(注意,雖然原始芯片是低功耗的,但該組件的分接板不是低功耗的。)

結(jié)果是相當(dāng)混亂(但功能齊全?。┑慕M件集:

[站外圖片上傳中...(image-5b51d-1556494524948)]

一切正常后,我花了一點(diǎn)時(shí)間用線路板跳線組裝一個(gè)更整潔的版本:

[站外圖片上傳中...(image-e79bdd-1556494524948)]

2.編寫Arduino代碼

下一步是編寫基本代碼,讓我的面包板設(shè)備完成我想要它做的事情。其中一些是標(biāo)準(zhǔn)的,并包含在每個(gè)組件的現(xiàn)有示例代碼中。例如,使用DS18B20 測(cè)量溫度的代碼如下所示:


#include <DallasTemperature.h>

#include <OneWire.h>

//數(shù)據(jù)線插入Arduino上的端口2

#define ONE_WIRE_BUS 2

//設(shè)置oneWire實(shí)例與任何OneWire設(shè)備通信(不僅僅是Maxim / Dallas溫度IC )

OneWire oneWire(ONE_WIRE_BUS);

//將我們的oneWire引用傳遞給Dallas Temperature。

DallasTemperature temp_sensor(&oneWire);

void setup(){

  Serial.begin(9600);

  temp_sensor.begin();

  Serial.println("DS18B20 Temperature Test\n\n");

  delay(300);//讓系統(tǒng)穩(wěn)定

}//end "setup()"

void loop(){

  Serial.print("Requesting temperatures...");

  temp_sensor.requestTemperatures(); //發(fā)送命令獲取溫度



  Serial.print("Temperature is: ");

  float temp_reading = temp_sensor.getTempCByIndex(0);

  Serial.println(temp_reading);

  delay(1000);

}// end loop()

有許多第三方庫(kù)提供Arduino Pro Mini的低功耗使用選項(xiàng)。我選擇了GitHub上Rocket Scream庫(kù)。家庭自動(dòng)化社區(qū)Andreas Rohner提供了有關(guān)修改Arduino Pro Mini以實(shí)現(xiàn)低功耗的良好信息。此項(xiàng)目的示例用法是:


// **** INCLUDES *****

#include“LowPower.h”

void setup()

{

//此庫(kù)無(wú)需設(shè)置

}

void loop()

{

//使用ADC進(jìn)入8秒的斷電狀態(tài)和BOD模塊禁用

LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);

//在這里做點(diǎn)什么

//示例:讀取傳感器,數(shù)據(jù)記錄,數(shù)據(jù)傳輸。

}

WiSOL Sigfox芯片可以使用標(biāo)準(zhǔn)AT命令進(jìn)行通信(產(chǎn)品數(shù)據(jù)表中包含基本示例)。對(duì)于這個(gè)項(xiàng)目,我只需要兩個(gè)功能:

  • 發(fā)送消息: 我將底層的AT命令封裝起來(lái),以便更容易發(fā)送命令,例如,測(cè)試設(shè)備和消息:

String send_at_command(String command, int wait_time){

  altSerial.println(command);

  delay(wait_time);

  return recv_from_sigfox();

}

void test_sigfox_chip(){

  Serial.println("Sigfox Comms Test\n\n");

  altSerial.begin(9600);

  delay(300);//Let system settle



  Serial.println("Check awake with AT Command...");

  chip_response = send_at_command("AT", 50); 

  Serial.println("Got reponse from sigfox module: " + chip_response);



  Serial.println("Sending comms test...");

  chip_response = send_at_command("AT", 50); 

  Serial.println("Comms test reponse from sigfox module: " + chip_response);

  chip_response = send_at_command("AT$I=10", 50); 

  Serial.println("Dev ID reponse from sigfox module: " + chip_response);

  chip_response = send_at_command("AT$I=11", 50); 

  Serial.println("PAC Code reponse from sigfox module: " + chip_response);

}

//message send

chip_response = send_at_command("AT$SF=" + hex_bits, 10000);

Serial.println("Reponse from sigfox module: " + chip_response);

  • 進(jìn)入低功耗(睡眠)模式: 我選擇了基本的睡眠模式,雖然這個(gè)芯片也支持“深度睡眠”選項(xiàng)。從1.5μA到<1μA,似乎沒(méi)有什么值必要,因?yàn)?.5μA的靜態(tài)電流消耗超出了我的目的。睡眠/喚醒周期代碼如下所示:

//Sigfox sleep mode enabled via AT$P=1 command

// to wake need to set UART port low (see AX-SIGFOX-MODS-D.PDF for further details)

void set_sigfox_sleep(bool go_sleep){

  String chip_response;

  if (go_sleep){

    //send go sleep AT command

    chip_response = send_at_command("AT$P=1", 100); 

    Serial.println("Set sleep response: " + chip_response);

  }else{

    //wake up sigfox chip

    altSerial.end();

    pinMode(TX_PIN, OUTPUT);

    digitalWrite(TX_PIN, LOW);

    delay(100);

    altSerial.begin(9600);   

  }

}

位組合:

我決定對(duì) Sigfox消息使用 位組合 ; 由于Sigfox消息最多為12個(gè)字節(jié),因此最好將盡可能多的數(shù)據(jù)壓縮到每個(gè)消息中。例如,假設(shè)溫度傳感器返回的溫度將在-40到+80攝氏度之間浮動(dòng)。C ++中的float使用4個(gè)字節(jié)的內(nèi)存,但如果沒(méi)有必要,您不希望使用12字節(jié)消息的4個(gè)字節(jié)發(fā)送數(shù)字。通常,您只需要知道一個(gè)半精度的溫度值,這樣就可以將整個(gè)可能的溫度范圍壓縮為8位(1個(gè)字節(jié)),因?yàn)橥ㄟ^(guò)將-40到+80的范圍限制為一半-degree增量,您只有240個(gè)可能的值,如下所示:


0b00000000 [0] = -40

0b00000001 [1] = -39.5

0b00000010 [2] = -39

...

0b11101111 [239] = 79.5

0b11110000 [240] = 80

為了節(jié)省更多空間,我將范圍限制在-10到+50攝氏度,精度為半度,溫度需要7位,光照水平需要5位(0到1,000),打開/關(guān)閉需要1位或者設(shè)備移動(dòng),4位消息序列號(hào),所以我可以發(fā)現(xiàn)任何錯(cuò)過(guò)的消息。所以,我的基本傳感器只需要使用我12字節(jié)可用消息空間中的18位,如下所示:

[站外圖片上傳中...(image-e2d5e0-1556494524948)]

我調(diào)整了一位組合功能,它們將獲取所有傳感器數(shù)據(jù),以及我想要用于每個(gè)傳感器數(shù)據(jù)的位數(shù),并將它們打包成一個(gè)12字節(jié)的值:


#ifndef BITPACKER_H_INCLUDED

#define BITPACKER_H_INCLUDED

#include <stdint.h>

#define BIT(n)                  ( 1UL<<(n) ) //UL = unsigned long, forces chip to use 32bit int not 16

#define BIT_SET(y, mask)        ( y |=  (mask) )

#define BIT_CLEAR(y, mask)      ( y &= ~(mask) )

#define BIT_FLIP(y, mask)      ( y ^=  (mask) )

/*

        Set bits        Clear bits      Flip bits

y        0x0011          0x0011          0x0011

mask    0x0101 |        0x0101 &~      0x0101 ^

        ---------      ----------      ---------

result  0x0111          0x0010          0x0110

*/

//! Create a bitmask of length \a len.

#define BIT_MASK(len)          ( BIT(len)-1 )

//! Create a bitfield mask of length \a starting at bit \a start.

#define BF_MASK(start, len)    ( BIT_MASK(len)<<(start) )

//! Prepare a bitmask for insertion or combining.

#define BF_PREP(x, start, len)  ( ((x)&BIT_MASK(len)) << (start) )

//! Extract a bitfield of length \a len starting at bit \a start from \a y.

#define BF_GET(y, start, len)  ( ((y)>>(start)) & BIT_MASK(len) )

//! Insert a new bitfield value \a x into \a y.

#define BF_SET(y, x, start, len)    \

    ( y= ((y) &~ BF_MASK(start, len)) | BF_PREP(x, start, len) )

namespace BitPacker {

    static uint32_t get_packed_message_32(unsigned int values[], unsigned int bits_used[], int num_vals){

        uint32_t retval = 0x0;

        int j = 0;

        for (int i=0;i<num_vals;i++){

            BF_SET(retval, values[i], j, j + bits_used[i]);

            j += bits_used[i];

        }

        return retval;

    }

    static uint64_t get_packed_message_64(unsigned int values[], unsigned int bits_used[], int num_vals){

        uint64_t retval = 0x0;

        int j = 0;

        for (int i=0;i<num_vals;i++){

            BF_SET(retval, values[i], j, j + bits_used[i]);

            j += bits_used[i];

        }

        return retval;

    }

}

#endif // BITPACKER_H_INCLUDED

3.原型電路

在為您的設(shè)備定制PCB電路之前,有必要確定一個(gè)更小,更整潔的原型電路。我選擇了 這個(gè)電路的 條形板版本。最終結(jié)果應(yīng)該是電路的更整潔和更緊湊的版本,這對(duì)于幫助修整最終的PCB設(shè)計(jì)非常有用。(這很重要,因?yàn)楦鶕?jù)經(jīng)驗(yàn),PCB越大,成本越高。)它還可以很好地了解最終產(chǎn)品可能需要哪種外殼。

我還使用了Fritzing,這是一款用于布置條形板或Veroboard電路的軟件。它允許您設(shè)計(jì)可以在條形板上復(fù)制的虛擬電路。我的原型電路在Fritzing看起來(lái)像這樣:

[站外圖片上傳中...(image-27f4c0-1556494524948)]

這導(dǎo)致了這個(gè)實(shí)際(工作)電路:

[站外圖片上傳中...(image-1a3ac3-1556494524948)]

4.設(shè)計(jì)和印刷PCB

為了設(shè)計(jì)我的PCB,我使用了 Autodesk Eagle,這是一款可以免費(fèi)用于小板(<80cm)的軟件,并且有許多組件庫(kù)(包括良好的第三方庫(kù),例如所有SparkFun和AdaFruit組件)。

我從這些SparkFun教程中學(xué)到了我需要了解的所有關(guān)于Eagle的知識(shí):

根據(jù)我的經(jīng)驗(yàn),我想提出一些建議:

  • 經(jīng)常保存!

  • 無(wú)論多么小,每次更改后都要進(jìn)行設(shè)計(jì)規(guī)則檢查(和重新檢查)。地面澆筑后重新檢查,即使更改不應(yīng)影響地面澆筑。(通過(guò)在銅板的外層填充開放的未使用區(qū)域,通常在板的外層上,然后將銅填充物與縫合過(guò)連接到地面來(lái)創(chuàng)建銅接地澆注。澆注的地面在缺少固體參考平面的雙層板上是有用的。它可以減少由于電容耦合引起的串?dāng)_。)

  • 當(dāng)使用非常小的元件(例如,FPGA表面貼裝元件)進(jìn)行布線時(shí),盡量不要在元件下方留下任何孔,以避免在沒(méi)有專業(yè)工具(例如,焊料回流焊)的情況下手工焊接或表面貼裝元件進(jìn)行原型測(cè)試時(shí)出現(xiàn)問(wèn)題,取放機(jī)械等)。很難確保手工焊接或焊膏不會(huì)位于元件下方并流入下方的布線孔(您無(wú)法看到的位置)。當(dāng)路由這些組件中的一些有多小時(shí),也很容易忘記。

換句話說(shuō),不要這樣做:

[站外圖片上傳中...(image-b46cbd-1556494524948)]

而是這樣做:

[站外圖片上傳中...(image-705c75-1556494524948)]

  • 對(duì)于較大的元件,盡量不要在元件支腳或焊盤附近設(shè)置布線孔,原因與上述相同。

我最終完全布線的電路板布局如下所示:

[站外圖片上傳中...(image-a77972-1556494524948)]

5.焊接表面貼裝元件

在這個(gè)項(xiàng)目開始時(shí),我不知道的是如何構(gòu)建包含表面貼裝元件(SMC)的原型。使用電鍍通孔(PTH)元件進(jìn)行原型制作(例如面包板)要容易得多,但是最終產(chǎn)品不會(huì)選擇PTH元件,因?yàn)镾MC更小更整潔。

當(dāng)您使用理想的SMC組件設(shè)計(jì)PCB布局,打印出來(lái)并想要將它們放在一起并進(jìn)行測(cè)試時(shí)會(huì)發(fā)生什么,但是您沒(méi)有任何表面貼裝機(jī)器(如拾取和放置機(jī)器或焊料回流爐)?你可以建立自己的回流爐,但如果你正在建造自己的回路,我認(rèn)為這種偏離的重點(diǎn)是有點(diǎn)耗時(shí)。并且,它幾乎是不必要的,因?yàn)槟梢酝ㄟ^(guò)足夠的練習(xí)手工焊接幾乎所有的SMC,并且您可以使用相對(duì)便宜的焊接氣槍來(lái)使工作更容易。

我使用 EEVBlog YouTube頻道來(lái)學(xué)習(xí)SMC焊接的基礎(chǔ)知識(shí),最后我將所有東西都焊接到0402組件(如果你呼吸太大,你會(huì)失去它們!)。有關(guān)上下文,請(qǐng)參閱此組件大小比較圖表:

[站外圖片上傳中...(image-9b29f6-1556494524948)]

我不建議在電路中使用0402組件。(我別無(wú)選擇,因?yàn)樗鼈兪翘炀€下的射頻網(wǎng)絡(luò)的一部分,更大的組件可能會(huì)影響天線性能。)事實(shí)上,0602組件也非常小而且很難焊接,但有一點(diǎn)練習(xí)它是非??尚械?。我建議第一批訂購(gòu)額外的PCB,純粹用于焊接實(shí)踐,因?yàn)槟愫芸赡軙?huì)弄亂你的第一次嘗試。

所需工具包括:

  • 烙鐵: 絕對(duì)值得為優(yōu)質(zhì)烙鐵付出更多。我從一個(gè)廉價(jià)的開始,幾個(gè)星期后,我放棄了它,用了一個(gè)更好的,一切都更容易。

  • 熱風(fēng)焊槍:我還買了一個(gè) 熱風(fēng)槍 ; 雖然它已被證明比我希望的更難使用(獲得正確的氣壓,所以你不會(huì)從板上吹掉小元件是一種藝術(shù)形式?。?,它已經(jīng)焊接了一些較小的(VFLGA)封裝集成電路,就像LIS3DH一樣,更容易。(我甚至不確定如何單獨(dú)用烙鐵做這件事,雖然顯然它是可能的。)當(dāng)你搞砸了東西時(shí),它也可以很容易地移除部件。

  • 鑷子:質(zhì)量好,非常精細(xì)的鑷子組對(duì)于拾取非常小的組件至關(guān)重要。

  • 放大鏡/放大鏡:為了放大焊接以檢查焊接不良,焊接橋,斑點(diǎn),漏針等,我發(fā)現(xiàn)了一個(gè)珠寶商的放大鏡,最好帶有內(nèi)置燈,非常實(shí)用。

6.測(cè)量功耗

功耗測(cè)量是一個(gè)非常困難的過(guò)程,但是非常重要。我希望我的設(shè)備能夠?qū)崿F(xiàn)超低功耗,因此可以使用小型電池工作一年(即900mAh CR2)。這意味著確保靜態(tài)電流(恒定電流消耗)盡可能小,降至低μA范圍,同時(shí)考慮到消息發(fā)送期間偶爾會(huì)有更高的電流消耗。盡管有許多方法可以評(píng)估電路的電流要求,但大多數(shù)方法的極低分辨率都很差。手動(dòng)機(jī)制,例如連接在電源線上的電流表,使用起來(lái)很麻煩,并且只給出了在特定時(shí)間使用了多少電流的快照(在某些情況下,對(duì)于任何可靠的測(cè)量都沒(méi)有足夠快的反應(yīng)速度)。

在我嘗試過(guò)的各種選項(xiàng)中,唯一最終使用的選項(xiàng)是Nordic Semiconductor 的 Power Profiler Kit(功率分析器套件)。它不是太貴(它和基板都大約100美元)而且效果非常好。(我唯一不滿的是,我無(wú)法讓它在Linux上可靠地工作,即使它是一個(gè)Python程序,所以我不得不在Windows下使用它。)

PPK不僅可以生成一個(gè)非常低分辨率(< 1a)的功耗恒定視圖,還可以生成一個(gè)運(yùn)行時(shí)間窗的平均值(這正是我計(jì)算電池壽命所需要的):

[站外圖片上傳中...(image-6656f2-1556494524948)]

7.對(duì)ATmega引導(dǎo)程序進(jìn)行編程

您可能焊接到PCB上的原始ATmega芯片可能無(wú)法使用正確的保險(xiǎn)絲設(shè)置(參見下文)或使用編程的引導(dǎo)加載程序進(jìn)行硬編碼,因此您可能需要對(duì)其進(jìn)行配置,以便正確操作電路板。對(duì)于第一次接觸印刷電路板的設(shè)計(jì)者/建造者來(lái)說(shuō),這十分令人困惑!

在設(shè)置從芯片供應(yīng)商處收到的原始ATmega芯片時(shí),有三個(gè)主要任務(wù)需要解決。(注意:細(xì)節(jié)參考ATmega328P,但其中大部分也適用于ATmega系列中的其他部分):

保險(xiǎn)絲設(shè)置:

熔絲是非易失性位,定義了芯片行為方式的許多可編程方面。有三個(gè)熔絲字節(jié),每個(gè)字節(jié)有8位:低字節(jié),高字節(jié)和擴(kuò)展字節(jié)。例如,它們控制什么類型的時(shí)鐘驅(qū)動(dòng)芯片或控制掉電檢測(cè)器(BOD)觸發(fā)的電壓。BOD在設(shè)定電壓下停止代碼執(zhí)行,以避免在功率過(guò)低時(shí)不可靠的操作。

默認(rèn)值在工廠提供的芯片中設(shè)置。這些可能適合芯片的預(yù)期用途。但如果沒(méi)有,他們需要改變。這是通過(guò)SPI總線使用合適的接口完成的,例如Ardiuno Uno板。這里這里有一些很好的指導(dǎo)。

引導(dǎo)程序:

運(yùn)行項(xiàng)目應(yīng)用程序所需的代碼需要加載到芯片中。通常使用FTDI頭設(shè)備通過(guò)USB將芯片連接到PC上。在這種情況下,芯片需要安裝引導(dǎo)加載程序以便于此操作。實(shí)際上,這是一個(gè)加載程序的程序,但是它是通過(guò)使用適當(dāng)接口的SPI總線加載的。

對(duì)于這個(gè)項(xiàng)目,我使用一個(gè)單獨(dú)的Arduino UNO來(lái)啟動(dòng)我的ATmega芯片,如下所示:

  1. 對(duì)于引導(dǎo)加載程序,請(qǐng)使用Nick Gammon 的 ATmega芯片編程器

  2. 下載ZIP文件

  3. 解壓ATmega_Board_Programmer文件夾(例如,到Arduino IDE Libraries目錄)

  4. 打開ATmega_Board_Programmer程序(譯者注:.ino文件)

  5. 將標(biāo)準(zhǔn)Arduino Uno連接到PC

  6. 將板設(shè)置為“Arduino / Genuino Uno”并設(shè)置正確的端口

  7. 上傳ATmega_board_programmer程序

  8. 斷開Uno與PC的連接并將其連接到目標(biāo)芯片,如下所示:

| Uno | Target |

| ------- | ---------- |

| D10 | Reset |

| D11 | MOSI |

| D12 | MISO |

| D13 | SCK |

| Gnd | Gnd |

| +5V | Vcc |

9.將Uno重新連接到PC - >設(shè)置端口 - >運(yùn)行串行監(jiān)視器115200波特

10.引導(dǎo)加載程序應(yīng)立即運(yùn)行并在串行監(jiān)視器窗口中顯示結(jié)果; 按照串行窗口中的說(shuō)明進(jìn)行操作(例如,“L”表示加載引導(dǎo)加載程序)

11.請(qǐng)注意,引導(dǎo)加載程序會(huì)將芯片設(shè)置為使用內(nèi)部8MHz時(shí)鐘; 如果你有一個(gè)外部晶振,這可以修改(見程序中的注釋)

程序代碼加載:

一旦芯片安裝了引導(dǎo)加載程序,就可以通過(guò)FTDI接口加載程序代碼。在開發(fā)人員PC上運(yùn)行的Arduino IDE可以通過(guò)該接口將應(yīng)用程序代碼直接加載到芯片。

8.打印PCB,購(gòu)買組件,制造和組裝

要從面包板轉(zhuǎn)向批量生產(chǎn),您需要各種資源(譯者注:國(guó)內(nèi)在某寶上都可以購(gòu)買):

  • 硬件組件:對(duì)于電路板,你需要各種元件,如各種電阻,電容,傳感器,集成電路等。你可以在像亞馬遜這樣的主流網(wǎng)站上找到一些,但我推薦一些特定于硬件的網(wǎng)站作為更好的選擇。我主要使用 DigiKey ; MouserFarnell 也很好。

  • PCB打?。?/strong> 一旦您設(shè)計(jì)了PCB并創(chuàng)建了指定打印方式的Gerber文件,您將需要找到一家公司進(jìn)行打印。SparkFun 在“挑選PCB制造商”下提出了一些值得一看的建議。我使用 Multi-CB 并發(fā)現(xiàn)它們非常好,及時(shí)且價(jià)格具有競(jìng)爭(zhēng)力,但我不得不通過(guò)銀行轉(zhuǎn)賬支付,因?yàn)樗麄儾惶峁┰诰€支付選項(xiàng)。

  • PCB制造: 一旦您的PCB完全設(shè)計(jì),您的組件就會(huì)被購(gòu)買并手工焊接,并且您的最后一個(gè)原型進(jìn)行了測(cè)試,現(xiàn)在是時(shí)候批量生產(chǎn)了。我從PCBCart得到了一個(gè)非常合理的報(bào)價(jià),其中包括匯編和ATmega芯片編程。由于我還沒(méi)有制造電路板,我不能評(píng)論它們的質(zhì)量或服務(wù)。

9.做后端開發(fā)

所以你已經(jīng)構(gòu)建了你的設(shè)備,它在Sigfox網(wǎng)絡(luò)上發(fā)送消息(主要是在Sigfox服務(wù)器上),現(xiàn)在該怎么辦?您將如何處理這些消息以及如何處理它們

Sigfox回調(diào)

首先要做的是讓Sigfox服務(wù)器將您設(shè)備收到的任何消息轉(zhuǎn)發(fā)給您控制的Web服務(wù)器或服務(wù)。關(guān)于如何實(shí)現(xiàn)這一點(diǎn),Sigfox系統(tǒng)有很多選項(xiàng),但我認(rèn)為最簡(jiǎn)單的方法是構(gòu)建自己的RESTful Web服務(wù)(如下所述),并讓Sigfox服務(wù)器使用消息數(shù)據(jù)向您的新服務(wù)發(fā)出HTTP請(qǐng)求。這可以在Sigfox后端通過(guò)使用設(shè)備的回調(diào)機(jī)制來(lái)完成,您可以根據(jù)需要從包括原始消息數(shù)據(jù)在內(nèi)的可用變量列表中指定發(fā)布的變量或URL參數(shù):

[站外圖片上傳中...(image-8a7934-1556494524948)]

RESTFul Web服務(wù)

RESTful Web服務(wù)是現(xiàn)代API接口,在Web上無(wú)處不在。有很多方法可以創(chuàng)建它們,但我決定先使用Go編程語(yǔ)言,因?yàn)樗俏蚁胍獙W(xué)習(xí)的語(yǔ)言,其次,因?yàn)樗苋菀淄ㄟ^(guò)Docker進(jìn)行部署。Go中Web服務(wù)的基本結(jié)構(gòu)(保存到MongoDB數(shù)據(jù)庫(kù))如下所示:


// Handler for HTTP Post - "/sensordata"

// Register new sensor data

func NewSensorData(w http.ResponseWriter, r *http.Request) {

    var dataResource SensorDataResource

    // Decode the incoming Task json

    err := json.NewDecoder(r.Body).Decode(&dataResource)

    if err != nil {

        common.DisplayAppError(

            w,

            err,

            "Invalid Sensor Data format",

            500,

        )

        return

    }

    sensorData := &dataResource.Data

    context := NewContext()

    defer context.Close()

    c := context.DbCollection("SensorData")

    repo := &db.SensorDataRepository{c}

    // Insert a sensor data document

    repo.Create(sensorData)

    if j, err := json.Marshal(SensorDataResource{Data: *sensorData}); err != nil {

        common.DisplayAppError(

            w,

            err,

            "An unexpected error has occurred",

            500,

        )

        return

    } else {

        w.Header().Set("Content-Type", "application/json")

        w.WriteHeader(http.StatusCreated)

        w.Write(j)

    }

}

您可能構(gòu)建的用于從Sigfox服務(wù)器基本處理原始數(shù)據(jù)的大多數(shù)簡(jiǎn)單Web服務(wù)都具有類似的結(jié)構(gòu)。

我發(fā)現(xiàn)對(duì)Sigfox消息解析特別有用的東西是比特解包(為我之前在Arduino代碼中使用比特拆包來(lái)將盡可能多的數(shù)據(jù)壓縮到我的Sigfox消息中)。用于解壓縮數(shù)據(jù)的相應(yīng)Go代碼如下所示:


func bit(n uint64) uint64 {

    return 1<<n

}

func bit_set(y uint64, mask uint64) uint64 {

    return y | mask

}

func bit_clear(y uint64, mask uint64) uint64 {

    return y & ^mask

}

func bit_flip(y uint64, mask uint64) uint64 {

    return y ^ mask

}

func bit_mask(len uint64) uint64 {

    return bit(len) - 1

}

func Bf_mask(start uint64, len uint64) uint64 {

    return bit_mask(len) << start

}

func Bf_prep(x uint64, start uint64, len uint64) uint64 {

    return (x & bit_mask(len)) << start

}

func Bf_get(y uint64, start uint64, len uint64) uint64 {

    return (y>>start) & bit_mask(len)

}

func Bf_set(y uint64, x uint64, start uint64, len uint64) uint64 {

    return (y & ^Bf_mask(start, len)) | Bf_prep(x, start, len)

}

IFTTT集成

最后,就使您的設(shè)備完成數(shù)據(jù)日志記錄之外的功能而言,將其與其他設(shè)備或生態(tài)系統(tǒng)集成的最簡(jiǎn)單方法可能是通過(guò)If This That That(譯者注:IFTTT連接你所有的應(yīng)用和設(shè)備。),它是許多不同API和系統(tǒng)的融合。一旦您將設(shè)備連接到IFTTT,您可以訪問(wèn)現(xiàn)有的后續(xù)行動(dòng)。例如,“如果[您的設(shè)備發(fā)送X],然后[發(fā)送電子郵件給Y],或[讓Alexa說(shuō)Y],或[打開Y室中的飛利浦Hue燈],”或者其他無(wú)數(shù)的選項(xiàng)。

后續(xù)規(guī)劃

Siguino項(xiàng)目的下一步是為它開發(fā)3D外殼,通過(guò)Sigfox設(shè)備認(rèn)證計(jì)劃,調(diào)整天線以充分利用它,以及資助和組織設(shè)備的第一次生產(chǎn)運(yùn)行。

由于我這個(gè)項(xiàng)目的主要目的是了解技術(shù),我已經(jīng)在GitHub對(duì)所有軟件代碼和硬件開源 。如果您有任何疑問(wèn)或找到有價(jià)值的信息,請(qǐng)?jiān)谠u(píng)論中告訴我。

關(guān)于作者:
本文作者Scott Tattersall是一名自由軟件顧問(wèn)。擅長(zhǎng)將最新技術(shù)(Blockchain,Docker等)的知識(shí)與傳統(tǒng)和現(xiàn)代數(shù)據(jù)庫(kù)(關(guān)系,非關(guān)系,文檔存儲(chǔ),列數(shù)據(jù)庫(kù)等)和云部署,架構(gòu)和基礎(chǔ)架構(gòu)(Docker,Kubernetes,AWS)的豐富經(jīng)驗(yàn)相結(jié)合。

原文鏈接:How to build custom IoT hardware with Arduino

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容