It is possible to buy small NRF51822 modules like the black “daughter-board” in the picture above for about €2. The motherboard it connects to breaks all the pins out to various headers, provides an JTAG/SWD port and a USB/Serial interface. These motherboards cost around $6 on Aliexpress.
I was curious about micropython on this platform so I took the following steps:
First, I downloaded the Nordic Semiconductors command line tools from here
They were then installed as follows:
sudo dpkg -i nRF-Command-Line-Tools_10_6_0_Linux-amd64.deb
(I had to fiddle with my PATH environment variable to make the programs available to the script used later).
Next, the motherboard and JTAG interfaces were plugged in to a USB port.
Micropython was compiled and downloaded as follows (Note, I had an arm cross compiler already on my system.):
git clone https://github.com/micropython/micropython.git micropython
cd micropython
make -C mpy-cross
cd ports/nrf
./drivers/bluetooth/download_ble_stack.sh
make submodules
make BOARD=wt51822_s4at SD=s110 sd
The last line targets a particular board that is compatible with the little cheap Aliexpress one, it also includes the Bluetooth soft-device and flashes the board.
All that seemed to work ok and I tried to connect to the board over a serial terminal: No success. After a bit of searching I discovered file called mpconfigboard.h in the micropython/ports/nrf/boards/wt51822_s4at directory. This needs to be edited as follows so that TX and RX for the micropython shell are routed properly.
/* * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * * Copyright (c) 2017 Ayke van Laethem * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ // Datasheet for board: // https://4tronix.co.uk/picobot2/WT51822-S4AT.pdf #define MICROPY_HW_BOARD_NAME "WT51822-S4AT" #define MICROPY_HW_MCU_NAME "NRF51822" #define MICROPY_PY_SYS_PLATFORM "nrf51" #define MICROPY_PY_MACHINE_UART (1) #define MICROPY_PY_MACHINE_HW_SPI (1) #define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_PY_MACHINE_RTCOUNTER (1) #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_ADC (1) #define MICROPY_PY_MACHINE_TEMP (1) #define MICROPY_PY_RANDOM_HW_RNG (1) #define MICROPY_HW_HAS_LED (0) // UART config #define MICROPY_HW_UART1_RX (11) #define MICROPY_HW_UART1_TX (9) #define MICROPY_HW_UART1_HWFC (0) // SPI0 config #define MICROPY_HW_SPI0_NAME "SPI0" #define MICROPY_HW_SPI0_SCK (1) #define MICROPY_HW_SPI0_MOSI (2) #define MICROPY_HW_SPI0_MISO (3)Note the changes to MICROPY_HW_UART1_RX and MICROPY_HW_UART1_TX.
I repeated the last “make” command and hey presto : I was able to type python into a serial terminal!
There are a couple of little problems:
1) You can’t paste large amounts of python into the terminal as it overflows the serial buffer in the device
2) The range of pins available is restricted as this board is not quite the same as the wt51822_s4atAnyway, it’s a start
My version of configs: https://svn.mavipet.sk/svn/ARM-projects/extsources/micropython/ports/nrf/boards/ble400/
Working all pins and LEDS 1-4 (port support max 4 leds 😦 )
LikeLike
Thanks for that. Very nice
LikeLike
hi, can you send link from your bin or hex file?
LikeLike
I put the firmware hex file up on pastebin. I believe this is the correct version but I am not sure. Just copy the pastebin text and paset it into a file
LikeLike
Here is the link: https://pastebin.com/wiy0pcSY
Let me know if it works
LikeLike
Thank you for your fast response.
I save it as .hex and upload code into nrf51822 nothing shows up in terminal.
as i build from micropython without S110 everything is ok but then add S110 and nothing works.
link to my build without s110: https://pastebin.com/6JVuLaSc
link to my build with s110: https://pastebin.com/fCDSutrZ
can you test my hex files?
LikeLike
Hi Amir, I no longer have that board so I can not debug your hex files. I do have a BBC microbit (V1) which includes an NRF51822. I may be able to experiment in a meaningful way with that however the serial TX/RX pins will likely be different.
LikeLike
Hi Amir, I think I have a solution for you. This worked for me on the BBC Microbit. When you copy the s110 version of the hexfile to the device this does not seem to include the softdevice. I experienced the same problems as you did when I tried the s110 version. What I did next was to flash the softdevice hex file to the nrf51822. I then flashed the micropython hex file and the system worked again. This is related to interrupt vector tables I’m supposing. In my case, the softdevice hex file was found at micropython/ports/nrf/drivers/bluetooth/s110_nrf51_8.0.0/s110_nrf51_8.0.0_softdevice.hex
When you program the second hex file be sure NOT to erase the entire device as you will be back where you started then. I hope this helps
LikeLike
Thanks a lot.
It’s working.
🙂
LikeLike
Cool!
LikeLike
Hi FDUIGNAN, the way you mention above working precisely, but in micropython as I try to use BLE . this error happend:
“OSError: can’t apply GAP parameters”
but when I use arduino, BLE works
do you have any idea how I can fix this?
Thanks.
LikeLike
Hi Amir, do you have any code that I can see?
LikeLike
The code is so simple I’ve just try to enable BLE
import ble
ble.enable()
LikeLike
Hi Amir, I have been able to replicate your fault. The behavior is the same on the Microbit as your board. I tried a modified version of one of the examples as follows:
from ubluepy import Service, Characteristic, UUID, Peripheral, constants
def event_handler(id, handle, data):
global rtc
global periph
global serv_env_sense
global notif_enabled
if id == constants.EVT_GAP_CONNECTED:
print(“Connected”)
elif id == constants.EVT_GAP_DISCONNECTED:
print(“Disconnected”)
elif id == constants.EVT_GATTS_WRITE:
print(“Gatt Write”)
service_id=UUID(“0x1234”)
characteristic_id=UUID(“0x5678″)
myservice=Service(service_id)
characteristic_properties=Characteristic.PROP_WRITE | Characteristic.PROP_READ
periph = Peripheral()
periph.addService(my_service)
mycharacteristic = Characteristic(characteristic_id, props=characteristic_properties)
myservice.addCharacteristic(mycharacteristic)
periph = Peripheral()
periph.addService(myservice)
periph.setConnectionHandler(event_handler)
periph.advertise(device_name=”ioprog”, services=[myservice])
But this fails on the line “myservice=Service(service_id)”
with the error:
OSError: can’t apply GAP parameters
The error is produced in ble_drv.c (I saw your post on the micropython forum)
// set up security mode
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
const char device_name[] = “micr”;
if ((err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)device_name,
strlen(device_name))) != 0) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT(“can’t apply GAP parameters”));
}
I modified the code as follows:
char message_number[20];
int index=9;
message_number[10]=0;
while(index >=0)
{
message_number[index]=(err_code % 10)+’0′;
err_code = err_code / 10;
index –;
}
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT(message_number));
This printed the error code in the python terminal as follows:
OSError: 0000000002
Looking through the header files I see this:
s110_nrf51_8.0.0_API/include/nrf_error.h:#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
So it would seem that the softdevice has not been enabled is the cause of the error.
I will continue to investigate for a bit
LikeLike
One more thing:
If I modify the code in ble_drv.c as shown below it tells me that the error is:
NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION
This suggests that the module is already enabled. Something is going wrong down at the driver level or at least with its interface with Micropython
#if (BLUETOOTH_SD == 110)
#if BLUETOOTH_LFCLK_RC
uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION,
softdevice_assert_handler);
printf(“LFCLK_RC \r\n”);
#else
uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM,
softdevice_assert_handler);
#endif // BLUETOOTH_LFCLK_RC
#endif // (BLUETOOTH_SD == 110)
if (err_code)
{
printf(“sd_softdevice_enable %u\r\n”,(unsigned int)err_code);
}
LikeLike
Hi FDUIGNAN,
Finally it works, just build again from last version of Micropython.
LikeLike
Thanks for letting me know Amir!
LikeLike