2018年4月20日 星期五

如何用ESPlorer來撰寫NodeMCU ESP8266的LED閃爍程式

ESP8266 程式編輯環境主要分成兩種,Arduino IDE 與ESPlorer。ESPlorer是使用Lua語言撰寫程式。Lua是個非常間易的語法,很容易學習。
NodeMCU使用ESPlorer來編輯,有兩個軟體先安裝。
1.先下載ESPlorer軟體,下載路徑 http://esp8266.ru/esplorer-latest/?f=ESPlorer.zip
ESPlorer
2.NodeMCU機板需要更新NodeMCU最新的Firmware(nodemcu_latest.bin),利用ESP8266 Flasher(NODEMCU FIRMWARE PROGRAMMER)軟體來更新Firmware,這樣NodeMCU機板才可以使用ESPlorer撰寫Lua程式,之前因為機板沒有燒錄NodeMCU Firmware,ESPlorer編譯好的程式是無法燒錄到機板上,這點要特別注意。
ESP8266 Flasher下載路徑:https://github.com/nodemcu/nodemcu-flasher
NodeMCU Flasher_Config
完成前兩步驟就可以開始用Lua編輯程式了。ESPlorer Baud rate 要選擇9600 ,才不會出現亂碼。按Open就可以與NodeMCU連接,按NodeMCU機板的RST按鍵,就會出現如下圖。
ESPlorer_1_
接著來寫個簡單的程式來試試看,讓機板上的LED閃爍,程式如下。
ESP_LED = 4                       -- NodeMCU pin no. (D4)
gpio.mode( ESP_LED, gpio.OUTPUT ) --設定D4為輸出
-- turn on
tmr.alarm(0,500,1,function()      --每500ms執行一次
   if gpio.read(ESP_LED)==1 then
   gpio.write( ESP_LED, gpio.LOW )
   else
   gpio.write( ESP_LED, gpio.HIGH )
   end
end)

led_lua.png
按下Save to ESP存成led.lua ,按NodeMCU機板上的RST按鍵,讓後Upload led.lua到NodeMCU機板上,在輸入 dofile(“led.lua")按Send看到NodeMCU的LED每0.5秒閃爍一次。

#CSR #CSR8635 #藍芽 #藍芽立體聲喇叭 #電子外包 #PCB LAYOUT #電子設計 #學生專題製作#電路設計 #NodeMCU #ESP8266 #單晶片程式設計

2018年4月18日 星期三

NodeMCU開發板ESP8266 WiFi模組介紹

NodeMCU是安信可科技(Ai-Thinker)公司(http://www.ai-thinker.com)做的開發板。搭配樂鑫(Espressif)公司(https://espressif.com)的ESP8266 ESP12的WiFi模組,如下圖。
nodemcu-lua-wifi-v3-esp8266-wifi
ESP8266晶片由上海樂鑫公司所開發出來,是顆32-bit單晶片處理器,整合了支援IEEE802.11 b/g/n的WiFi晶片。與Arduino週邊接腳相容,所以可以支援Arduino的感應器,價格十分便宜且操作簡單,也容易取得,已成為物連網應用的最熱門的選擇。

ESP8266硬體規格如下
  • CPU選用32-bit Tensilica Xtensa LX3,處理速度80MHz。
  • ROM/RAM方面提供64K Boot ROM,64K Instruction RAM與64K Data RAM。
  • 額外Flash擴充到4MB,可以儲存即時作業系統與應用程式。
  • 具有WiFi 802.11b/g/n 2.4G Radio ,可以設定為AP、Station或AP+Station等各種網路應用模式。
  • 有13支GPIO,支援PWM、I2C、UART、SPI及10-bit ADC等週邊功能,沒有DAC功能。

ESP8266程式編輯環境

ESP8266晶片系列模組
ESP8266系列
NodeMCU是支援ESP8266軟硬件開發非常好用的開發板,NodeMCU PIN腳定義,如下圖。
NodeMCU1

NodeMCU驅動程式,目前NodeMCU板子USB轉UART的晶片有兩種,CH341與CP2102這兩種,驅動程式下載路經分別如下。

NodeMCU韌體燒錄程式(NodeMCU Flasher),下載路徑 https://github.com/nodemcu/nodemcu-flasher
NodeMCU Firmware下載路徑 https://github.com/sleemanj/ESP8266_Simple/raw/master/firmware/ai-thinker-0.9.5.2-115200.bin
NodeMCU Flasher
#CSR #CSR8635 #藍芽 #藍芽立體聲喇叭 #電子外包 #PCB LAYOUT #電子設計 #學生專題製作#電路設計 #NodeMCU #ESP8266 #單晶片程式設計

2018年4月16日 星期一

Nordic nRF52832 DFU介紹

什麼是DFU?就是Device Firmware Update 。Nordic提供nRF Toolbox APP可以在Play商店下載。可以經由over-the-air(OTA)方式來更新程式。
Screenshot_20180222-131341
如何讓你裝置有DFU功能?可以分成三個部份。
1.先修改Bootloader程式,因為有專屬private key
2.燒錄檔.hex轉成.zip
3.利用nRF Toolbox的DFU來更新程式
Bootloader程式,請參考nRF5-SDK-zip 的examples/duf/bootloader_secure_ble的範例。我是用Keil去編譯,出現錯誤,如下。
dfu-1
顯示錯誤訊息如下
#error “Debug public key not valid for production. Please see https://github.com/NordicSemiconductor/pc-nrfutil/blob/master/README.md to generate it"
點選以上網址,根據網頁內容步驟去執行,步驟如下。
1.下載pc-nrfutil 的檔案。
3.安裝pip
4.在Windows系統,新增環境變數內系統變數的Path路徑如下。
C:\Python27\Scripts;C:\Python27\;
5.接下來的指令都是在DOS畫面下執行,請在開始的搜尋檔案處,打上cmd,就會出現如下圖示。
dos
6.Installing from PyPi ,請在DOS畫面輸入以下指令
pip install nrfutil
7.PyInstall,請在DOS畫面輸入以下指令
pip install pyinstaller
8.在DOS畫面,跳到下載pc-nrfutil檔案的pc-nrfutil-master資料夾下,執行以下的指令
pip install -r requirements.txt
python nordicsemi/__main__.py
python setup.py install
pyinstaller nrfutil.spec
9.產生key.pem,請在DOS畫面輸入以下指令,請把key.pem存到pc-nrfutil-master\nordicsemi\dfu\tests下。
nrfutil keys generate key.pem
10.把key.pem轉換成code ,請在DOS畫面輸入以下指令。把code如下圖紅色框框,複蓋到SDK的dfu_public_key.c
nrfutil keys display --key pk --format code key.pem
keypem
11.Keil編譯應該就可以成功了。
12.利用nRFgo Studio軟體把.hex燒錄到板子上,先燒錄SoftDevice,再燒錄Application,最後才燒錄Bootlader。這樣機板就有DFU功能。
13.把.hex轉成.zip檔案,請在DOS畫面輸入以下指令,選用nRF52xxx系列–hw-version 就填52,--sd-req 請參考下圖,--application填寫要燒錄的檔案名稱,--key-file key.pem就是dfu_public_key.c,不同key.pem就無法DFU,這一點要特別注意。app_dfu_package.zip是你要轉出的.zip檔案,名稱可以自訂。
nrfutil pkg generate --hw-version 52 --sd-req 0x9D --application-version 4 --application app.hex --key-file key.pem app_dfu_package.zip
SoftDevice
14.打開手機的nRF Toolbox APP,選擇DFU,把app_dfu_package.zip上傳到手機,選擇藍芽裝置,就可以更新程式了。
PS.  藍芽裝置要先進入Bootloader才可以DFU,藍芽裝置按住按鍵再上電就可以進入Bootloader。
#CSR #CSR8635 #藍芽 #藍芽立體聲喇叭 #電子外包 #PCB LAYOUT #電子設計 #學生專題製作#電路設計 #數位線路 #類比線路 #單晶片程式設計

2018年4月13日 星期五

Nordic nRF52832 Timer程式介紹

#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_drv_timer.h"
#include "bsp.h"
#include "app_error.h"

const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);

/**
 * @brief Handler for timer events.
 */
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    static uint32_t i;
    uint32_t led_to_invert = ((i++) % LEDS_NUMBER);

    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            bsp_board_led_invert(led_to_invert);  
            break;

        default:
            //Do nothing.
            break;
    }
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;

    //Configure all leds on board.
    bsp_board_leds_init();
 
    //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);

    nrf_drv_timer_extended_compare(
         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

    nrf_drv_timer_enable(&TIMER_LED);

    while (1)
    {
        __WFI();
    }
}
const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);設定為Timer0。
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context);Timer中斷副程式。
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;設定為default config。
nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);Timer初時化設定及中斷副程式。
nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);中斷時間轉為ticks.
nrf_drv_timer_extended_compare( &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
nrf_drv_timer_enable(&TIMER_LED);Timer啟動
此程式每500ms產生中斷,程式會跳到void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)去執行LED控制。




#CSR #CSR8635 #藍芽 #藍芽立體聲喇叭 #電子外包 #PCB LAYOUT #電子設計 #學生專題製作#電路設計

2018年4月11日 星期三

Nordic nRF52832 PWM Library介紹

#include "nrf.h"
#include "app_error.h"
#include "bsp.h"
#include "app_pwm.h"
#include "nrf_delay.h"

APP_PWM_INSTANCE(PWM0,0); // Create the instance "PWM0" using TIMER0.
void pwm_ready_callback(uint32_t pwm_id)    // PWM callback function
{
    ready_flag = true;
}
int main(void)
{
 ret_code_t err_code;
 
 /* 2-channel PWM, 1000Hz, output on p0.17 & p0.18 */
        app_pwm_config_t pwm0_cfg = APP_PWM_DEFAULT_CONFIG_2CH(1000L, 17, 18);
 
 /* Switch the polarity of the second channel. */
 pwm0_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
 pwm0_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_LOW;
 
 app_pwm_init(&PWM0,&pwm0_cfg,pwm_ready_callback);
 app_pwm_enable(&PWM0);
 
 ready_flag = false;
 while (app_pwm_channel_duty_set(&PWM0, 0, 0) == NRF_ERROR_BUSY);
 while (!ready_flag);
 ready_flag = false;
 while (app_pwm_channel_duty_set(&PWM0, 1, 0) == NRF_ERROR_BUSY);
 while (!ready_flag);
 
 uint32_t value;
        while (true)
        {
            for (uint8_t i = 0; i < 40; ++i)
            {
            value = (i < 20) ? (i * 5) : (100 - (i - 20) * 5);

            ready_flag = false;
            // Set the duty cycle - keep trying until PWM is ready... 
            while (app_pwm_channel_duty_set(&PWM0, 0, value) == NRF_ERROR_BUSY);

            // ... or wait for callback. 
            while (!ready_flag);
            APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM0, 1, value));
            nrf_delay_ms(25);
            }
        }
}
函式APP_PWM_INSTANCE(PWM0,0) ;是指PWM0模組時序是TIMER0。
函式APP_PWM_DEFAULT_CONFIG_2CH(1000L, 17, 18);PWM模組有兩個頻道輸出,為channel0為P0.17,channel1為P0.18,頻率為1000Hz。
pwm0_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
channel0 的PWM POLARITY為High。
pwm0_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_LOW;
channel1 的PWM POLARITY為Low。
函式app_pwm_init(&PWM0,&pwm0_cfg,pwm_ready_callback);PWM0初時化設定及設定callback函式。
函式app_pwm_enable(&PWM0);啟動PWM0
函式app_pwm_channel_duty_set(&PWM0, 0, value);channel0 pwm duty設定,value為0~100。

2018年4月9日 星期一

Nordic nRF52832 PWM driver程式介紹

nRF52832 有三個PWM模組,每個模組有4各channels,所以總共有12各channels可以使用,每支GPIO都可以設定為PWM。以下圖是PWM模組的方塊圖。
PWM 方塊圖
Wave Counter有兩種模式,分別為PWM up counter與PWM up and down counter。主要是產生duty-cycle pulses,如下兩圖示。
PWM up counter
PWM up and down counter
Decoder with EasyDMA,分成四種模式Common、Grouped、Single、WaveForm,如下圖示。
Decoder
以下是SDK的PWM範例程式
static void demo5(void)
{
    NRF_LOG_INFO("Demo 5");

    /*
     * This demo, similarly to demo1, plays back a sequence with different
     * values for individual channels. Unlike demo 1, however, it does not use
     * an event handler. Therefore, the PWM peripheral does not use interrupts
     * and the CPU can stay in sleep mode.
     * The LEDs (1-4) blink separately. They are turned on for 125 ms each,
     * in counterclockwise order (looking at the board).
     */

    nrf_drv_pwm_config_t const config0 =
    {
        .output_pins =
        {
            BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
            BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
            BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
            BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED  // channel 3
        },
        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
        .base_clock   = NRF_PWM_CLK_125kHz,
        .count_mode   = NRF_PWM_MODE_UP,
        .top_value    = 15625,
        .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
        .step_mode    = NRF_PWM_STEP_AUTO
    };
    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
    m_used |= USED_PWM(0);

    // This array cannot be allocated on stack (hence "static") and it must
    // be in RAM (hence no "const", though its content is not changed).
    static nrf_pwm_values_individual_t /*const*/ seq_values[] =
    {
        { 0x8000,      0,      0,      0 },
        {      0, 0x8000,      0,      0 },
        {      0,      0, 0x8000,      0 },
        {      0,      0,      0, 0x8000 }
    };
    nrf_pwm_sequence_t const seq =
    {
        .values.p_individual = seq_values,
        .length              = NRF_PWM_VALUES_LENGTH(seq_values),
        .repeats             = 0,
        .end_delay           = 0
    };

    (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
}
PWM範例程式參數設定介紹
.output_pins 設定4組PWM channel的輸出PIN。
.base_clock設定基頻,NRF_PWM_CLK_16MHz、NRF_PWM_CLK_8MHz、NRF_PWM_CLK_4MHz、NRF_PWM_CLK_2MHz、NRF_PWM_CLK_1MHz、NRF_PWM_CLK_500kHz、NRF_PWM_CLK_250kHz、NRF_PWM_CLK_125kHz。可設定這8種頻率。
.count_mode設定Wave Counter模式,NRF_PWM_MODE_UP、NRF_PWM_MODE_UP_AND_DOWN。