Name: Roger

Posts by Roger Clark:

    New nRF52832 based smart watch available (ID107HR Plus)

    June 19th, 2017

    It looks like the same company who make the ID107 HR have brought out a new product called and ID107 Plus, which uses the better nRF52832 MCU

    I ordered 2 of these from AliExpress and they arrived a few days ago. However at the moment I can’t work out the best way to open the device to look inside.

    https://www.aliexpress.com/item/100-Original-Makibes-ID107-Plus-Smart-Bracelet-BT4-0-Heart-Rate-Monitor-Smartband-Pulse-Sports-Fitness/32809803432.html?spm=2114.13010608.0.0.RsxZli

     

    I’ve also contacted the company via an Alibaba PM to confirm if this is one of their products, or whether some other company are using the same model numbering system to pass their product of as being like the ID107 HR etc

    https://ido-smart.en.alibaba.com/?spm=a2700.8304367.0.0.jP93J4

     

     

     

    Externally the watch has the usual rubber strap

     

     

    But the main functional part of the watch is designed to be removed for charging

     

    And features a USB connector at one end (sorry for the focus on this photo , but you can clearly see the USB connector ūüėČ )

     

     

    Fortunately Curt White ( https://github.com/curtpw ) has sent me some photos of an ID107 Plus he has managed to take apart, and also some information about the internal connections.

     

    Firstly the USB is only connected to power and ground, so is only usable for charging.  I suppose it could be modified so that the SWD connections, for programming where wired to the normal USB  D+ and D- but this appears to be a difficult modification to make

    The watch seems to have the nRF52832 MCU as well as :-

    KX022 accelerometer

    Si1143 optical sensor for HR

    Azoteq IQS263

    Macronix MX25L series USON package SPI flash

    Curt informs me that he thinks the MCU pins used for these are as follows

     

    #define  KX022_SCL                5
    #define  KX022_SDA                3
    #define  KX022_INT                6
    #define  KX022_ADDR               4
    #define  KX022_NCS                7

    #define  MX25_SO                  27
    #define  MX25_CE                  28
    #define  MX25_SCK                 30
    #define  MX25_SI                  31

    #define  SI1143_SCL               18
    #define  SI1143_SDA               10
    #define  SI1143_INT                8
    #define  SI1143_LED                9

    But I have not verified this myself

     

    Here are the photos Curt sent me

     

     

    I before taking my watch apart (or breaking it apart), I have looked at the Bluetooth Services which are advertised by this device, and it only advertises 1 primary service with UUID 0x0AF0 . This is a unregistered 16 bit UUID,i.e Its not a service ID which has been registered with Bluetooth.org

    Within this service there are 4 characteristics

    0x0AF6 Рread  / write

    0x0AF7 – read / notify

    0x0AF8 – read / notify

    0x0AF9 – read / write

     

    All of these characteristics read as 0x00 but I have not tried writing to them.

    Ideally one of these would be a DFU service in disguise, but at the moment its not possible to know if that’s the case, or possibly whether writing to one of these services would cause the device to go into DFU upload mode.

     

    I have asked the manufacturer via an Alibaba PM, to ask whether the device is updatable via DFU, and hopefully they will get back to me with more information (assuming they do make this device)

     

    If the manufacturer is not willing to give any information, one option is simply to compile a test application onto a nRF52832 dev board (I have the Nordic dev board as well as several nRF52832 based module boards), which advertises the same services, and then run the iOS or Android app, and see what comms occur e.g. what does the App send and what does it get back.

    I’ve also got a rooted Android phone, (running Lineage OS), so I can also install the VeryFit app that communicates with this device and copy the file back onto my PC and decompile it.

    I may be able to do the same thing on iOS as I have an old / rooted iPad; but it only runs iOS 6, which may not be compatible with the VeryFit app

     

     

    Its early days for customising this device but it does show a lot of promise, and if DFU could be used to upload firmware, it would make it very practical to use.

     

     

    Update.

    I got a response from the manufacturer confirming that they do make the ID107HR Plus and that it uses the nRF52, however they don’t really understand my question. I asked whether it is possible to upload via DFU, but they think that I want them to write custom firmware.

    And that the minimum order quantity for this is 50,000 units !!!

    I have now asked if they have phased out the nRF52

     

    I’ve also asked them if there is any way they can pre-flash just a DFU service (I didnt tell them what the firmware does as I don’t think their sales person understands) e.g. if we but 100 units and pay a premium for each item.

     

    I suspect they don’t want to get involved in such small things, but I may as well ask

     

    8 Comments "

    Arduino on the ID100HR fitness tracker

    June 18th, 2017

    Some time ago…, Goran Mahovlic commented about how he was trying to run Arduino on an IDo 003, fitness tracker / smart watch which uses the nRF51822. As I’ve been interested in smart watches for some time, I thought I’d buy the same watch, and join in the fun.

    Unfortunately the first watch I bought didn’t contain an nRF51822 (see my other post about nRF51 based smart watches), so I ordered 2 more of different types, and finally after another 2 weeks, an ID100HR arrived and to my relief it did use an nRF51822, even even better it was the QFAC variant which has 256k flash and 32k RAM.

     

    id100hr_front_smart_watch

    id100hr_back_smart_watch

     

    The spec for this watch are:

    MCU: Nordic nRF51822QFAC (256k flash , 32k RAM)

    Operating clock frequency: 16Mhz

    Realtime clock crystal : 32khz

    Display: 0.49 inch OLED display (64×32 pixels) which uses the SSD1306 display controller

    Motion sensor: Kionix kx022-1020

    Heart rate sensor: Silicon labs Si1142

    Battery: LiPo 60mAH

    Charger: USB cable with 3 pins (5V, GND, 5V), (No PSU is supplied). The cable just connects 5V from the USB cable, so the battery charge controller must be inside the watch.

    One push button and a vibration alert (motor)

     

    Pin Assignments for the most of these watches seems to be as follows

    RX pad P0.17
    TX pad P0.18
    Vibrate P0.07
    Button P0.04 Needs input_pullup
    Accelerometer (I2C)
    P0.10-16 possible range of pins used
    P0.16 SCL
    P0.15 Possibly IRQ
    P0.14 SDA
    OLED (SPI)
    P0.29 SPI MOSI
    P0.30 SPI SCK
    P0.0  Data/Command
    P0.1 Reset
    P0.2 Chip select

     

     

    Whats great about this watch, is that they have labelled the SWDIO and SWCLK pads, and also that they have even broken out 2 pins to 2 pads labelled TX and RX.

     

    So its easy to connect either a JLink or Blackmagic probe to the SWD pins to reprogram it.

     

     

     

     

    I also like to thank Goran Mahovlic for his work on the ID003 smart watch, and in turn to thank the Espruino guys for giving Goran something to work from…¬† http://forum.espruino.com/conversations/280747/

    9 Comments "

    Investigating a RCWL 9196 / RCWL-0516 “Radar” motion detector module

    June 18th, 2017

    A new type of “Radar” motion sensor has been getting a lot of attention in the last couple of months, but no one seemed to know how they worked, so I decided to buy a few of these very cheap devices (sub $1) and investigate possible methods of operation.

    The boards I bought use the RCWL 9196, but appear to have identical functionality to those with the RWCL-0516 chip on them

    This github site https://github.com/jdesbonnet/RCWL-0516/ contains loads of useful information on these boards, and there is also an excellent video by Andreas Spiess on YouTube https://www.youtube.com/watch?v=9WiJJgIi3W0

    Where the properties of these devices was explored.

    I hope to have taken this at least one step forward with my tests.

    The main difference in my approach is that I have connected a wire from the analogue signal output on the only IC on the board, into an analogue input on a STM32F103C8 (aka Blue Pill) board.

    The pin I connected to is Pin 12 on U1, (RCWL 9196 and is the output of the 2nd OpAmp in that chip).

    (Schematic from Joe Desonnet’s github account)

     

     

    My RCWL 9196 board is not exactly the same as this, but the pinout of the IC is the same.

    Also the RCWL 9196 is almost identical to the BIS0001

    http://www.ladyada.net/media/sensors/BISS0001.pdf

    Where pin 12 is labelled as 2Out

     

     

    I then wrote a very simple sketch in the Arduino IDE to print both the analogue signal from 2Out and also the normal digital output from the board

     

    void setup() {
    pinMode(PA0,INPUT);
    pinMode(PA1,INPUT);
    }
    void loop() {
    Serial.print(“0,”);
    Serial.print(analogRead(PA0));
    Serial.print(“,”);
    Serial.print(analogRead(PA1)+100);
    Serial.println(“,4500”);
    delay(10);
    }

    BTW. The reason I’m writing values of 0 at the beginning of the line of output and 4500 is because the Arduino IDE “Plotter” feature is auto ranging, and if I don’t include a lower an upper bound, the vertical scale constantly changes

    Looking at the output when nothing is moving I see this plot

    Green is the digital output (in this case its LOW / OFF), and the Red trace is the analog signal, which is close to half the 3.3V Vdd voltage supplied to the board.

    Note. The STM32F103C8 has an anlogue input range of 0 to 4096 (12 bit)

     

    If I start to wave my hand, starting with a small movement and then increasing, I see this plot.

     

    As you can see the hand movement causes an immediate effect on the output of the second OpAmp, but the value has to go above (or below) a threshold before the digital output triggers

     

    In this next plot. I was walking towards the sensor, and then stopped.

     

    As you can see the digital output holds for around 2 seconds after the end of the input fluctuations.

     

    The more interesting thing about this plot are the peaks and troughs at the start where I was walking towards the sensor.

    I thought this could be because its sensing the movement of my legs, so I devised a better test where I stood on a chair and dropped an object from the ceiling, and observed the results.

     

    I tried a variety of objects, and the best performing object that mimicked the properties of a person moving, turned out to be a damp sponge.

    I tried a dry sponge, but it had no effect on the sensor whatsoever, but as soon as I got it wet, it was immediately detected.

     

     

    In this plot the sponge is falling about 1m horizontally from the sensor, which is resting on a table about 1m from the ground.

    As you can see, there are still multiple peaks and troughs in the output signal.

    I know that there was some speculation that these devices work by using the Doppler effect,but this does not appear to be validated my the tests I have done.

    So my theory is that the peaks and troughs are caused by reflected signals from objects, interfering with the oscillator / transmitter.
    When I say interfering, I mean of wave propagation, where the reflected wave can be in phase with the oscillator or out of phase, resulting in the oscillator drawing more or less current.

    https://en.wikipedia.org/wiki/Interference_(wave_propagation)

    From Joe Desbonnet’s github repo,he observed that the oscillation frequency is around 3.1GHz with his module. So assuming my module is similar, then the wavelength of 3.1GHz is around 10cm.

    However in my tests, I am not sure the peaks and troughs match exactly with that frequency, and the effect I see if more consistent with perhaps twice that frequency.

     

    Doing some tests moving a piece of aluminium foil up and down, approximately 30cm, to 5 cm above the sensor observe these results when moving slowly

     

     

    And moving quickly

     

     

    What is fairly clear is that the interference is not from a single path, but rather that the aluminium foil (or the damp sponge), is reflecting signals directly from the device, but is also going to be reflecting, some reflections back to the device.

    So its a complex pattern of primary and secondary signals, with the strongest effect most likely to be the primary signal straight from the device (transmitter)

    Also just to complicate matters, the OpAmp IC is configured so that the output is always trying to return to a steady state.

    This can be seen when the device first turns on, and the analogue output initially is at its maximum, and takes around 10 seconds to stabilise to Vdd /2

     

    Looking at the schematic and also measuring the voltage from the RF oscillator / transmitter, using an oscilloscope. The oscillator output voltage, rises to around 0.4V very quickly.

    However OpAmp 1, in the RCWL9196 is configured as a high gain amplifier (and filter), whose non-inverting input will be initially 0V.

    The inverting input is fed from the output of the OpAmp via a resistor and capacitor network, and charges C7 via R6, and the RC network of R4 in parallel with C4

    I don’t know if the resistor values on my board are identical to the schematic, but a rough calculation on the RC charge time of the inverting input would be 22uF * 1M = 22 seconds.

    But thats the time to get to Vdd not to 0.4V, so I think its highly likely that the 11 seconds startup time, is the time taken to charge C7 to 0.4V.

    I observed the fluctuations of the input voltage from the oscillator using my scope, but the change was minimal; at around 4mV, and I was only able to measure this using capacitive coupling on the scope.

    So if C7 can charge from 0V to 0.4V in around 10 seconds, then it would compensate for a change in input from the osc (of 0.004V) in 1/100th of 10 seconds, i.e 1/10th Sec (100mS)

    This effect is also observable in practice, by moving an object towards the sensor and then holding it. As you normally see a peak or a tough, but very quickly the signal is pulled back to its steady state.

     

    I did attempt to increase the value of C7 from 22uF (226) a higher value, in the hope that I could make a much larger time constant, but I damaged the board somehow, whilst trying to do this, so I do not have any results for that test.

    BTW. I have 2 boards, but I don’t want to modify the second one in case I damage that one as well.

     

    So to sum up…

    My hypotheses, is that these devices are a oscillator / transmitter, and that the detection method is by wave propagation interference.

    This is consistent with many of the results I observed.

    1. Objects moving towards (or away) from the sensor, produce peaks and toughs rather than a steady state offset; which would be caused by the Doppler effect
    2. The peaks and troughs are complex, as the interference is generated by reflections of reflections.
    3. Waving a length of wire, (which would act as an inductor), near the sensor, produces little or no variation in the output
    4. As the unit has a range of around 4 or 5m, and detection does not seem to diminish strongly with increasing distance, it seems unlikely that the effect is being caused by capacitive coupling between the observed object and the oscillator (and its surroundings_

     

    And where does this leave us…

    Well, at the moment, I don’t see a use for these devices apart from their intended application of motion sensing.

    I think that using the analogue output from pin 12, is beneficial, as it can be used to get some indication of the scale of the detection, and would allow the trigger level, and hold time etc, to be controlled in the application (e.g. Arduino sketch).

     

    I think if a method was devised to be able to observe the output from the oscillator, without the current system that always returns the output to a mid point steady state, even if the oscillator is not in that state; that perhaps the device could be used more easily to perhaps determine the speed of an object. By determining the time difference between each peak.

    However even with the necessary hardware modifications to facilitate this, there would still be the problem of reflections of reflections; which would cause the data to be difficult if not impossible to analyse

     

     

    21 Comments "

    Arduino STM32 NeoPixels (WS2812B) using SPI DMA

    June 13th, 2017

    RGB LED strips (aka¬†Neopixels) have been around for a number of years now, so I’ve been somewhat behind the curve in not having tried these interesting devices until now.However I recently bought a 1M strip of 30 LEDS which feature the WS2812B device, from a local eBay vendor.

    As regular readers will know, my microcontroller of choice for most general purpose work is the cheap and trusty STM32F103C in conjunction with the Arduino API, so I checked if anyone had ported Adafruit’s NeoPixel library to the Arduino STM32, and found https://github.com/ANDnXOR/Adafruit_NeoPixel-ANDnXOR/.

    Unfortunately when I tried it, I occasionally got completely random LED colours and random flashing etc. Hooking up a logic analyser to the data pin, I found that the pulse timings produced by that library seemed considerably wrong, and were being caused by a combination of various factors including the compiler not caching the GPIO register address, and other things associated with call overhead and some inline assembler. There was also an issue with the USB Serial failing because for the entire time to send the data, all interrupts were disabled to ensure critical timing was not disturbed.

    I spent some time fixing this library (but have not published an updated version yet), and it worked OK, but I still had the issue with USB failing, So I thought that bit-banging the data to the LEDs seemed quite inefficient, as the STM32 possesses several independent subsystems which could be used for this purpose.

    The simplest and most obvious subsystem for sending a bit-stream is of course SPI, and the STM32 features DMA driven SPI, which would allow data to be sent to the LED’s while new data is prepared.

    Looking at the datasheet for the WS2812B,

    To send a “0” requires a pulse that is high for 400nS and low for 850nS (all values plus or minus 150nS)
    To send a logic 1 requires a pulse that is high for 800nS and low for 450nS (all values plus or minus 150nS)

    This is approximately a 1 to 2 ratio between the “mark” and “space” length (or vice versa)

    As the STM32F103 normal operating frequency is 72Mhz and the SPI PLL divider is available in powers of 2, I checked and found that 72Mhz / 32 = 2.25 Mhz, which equates to a pulse length of 444.44nS, and sending the binary pattern 100 results in a high pulse of 444ns followed by a low for 889nS (rounding to the nearest nS), and sending 110 results in a high pulse of 889nS and a low period of 444nS

    Both combinations are within the spec for the WS2812B.

    It should be noted at this point, that the older WS2812 has slightly different timings, e.g. a pulse of 350nS is required for a logic zero, so this device is not compatible with this method of sending data.

    Now that I knew that I could use bit triplets “100” and “110” to send a data “0” and “1” to the WS2812B, I needed a way to generate these triplets and concatenate them to produce the GRB data for each LED (The data order is Green Red Blue , not the traditional Red Green Blue), so I wrote this function which converts a single byte (colour channel) into the 24 bit (8 x 3 bit triplets)

     

    uint32_t convert(uint8_t data)
    {
      uint32_t out=0;
      for(uint8_t mask = 0x80; mask; mask >>= 1)  
      {
        out=out<<3;
        if (data & mask)
        {
          out = out | 0B110;//Bit high
        }
        else
        {
          out = out | 0B100;// bit low
        }
      }
      return out;
    }
    

    I used this function to build a buffer of “encoded” data buffer and then used the Arduino STM32 extended SPI function dmaSend() to send the buffer to the LED strip.

     

    Initial results of this were very promising, with the 30 LED strip being updated quickly, but I noticed that the first LED in the strip sometimes displayed the wrong colour.

    I hooked up my 100Mhz USB logic analyser, and looked at the data being and compared it with a bit-banged version I’d previously been working on.

     

    SPI version

    Bit-banged version

     

    And the length of the very first pulse (logic high), was 0.49uS long for SPI and 0.45us long for bit-banged.

     

    Reading the spec of the WS2812B, a pulse duration of < 550nS (0.55us) is supposed to be a logic zero, however my LED strip was treating this as a logic 1, and hence setting the Green channel to 10000000, or in a general case the MS bit was always set to 1, hence green values were never lower than 0x80 (50%)

    I don’t know why the WS2812B is treating a 490nS pulse as if it is longer than 550nS, but the only thing I can conjecture is that the pulse width being shown on the logic analyser is based on a different threshold voltage e.g. Vdd (3.3V) / 2. However according to the WS2812B spec, a High is signalled when the input voltage is 0.7 of its supply voltage which is nominally 5V, = 3.5V.
    I know that driving these devices using 3.3V logic is known to be problematic if the LED supply 5V because of this input voltage threshold, and that there are various workaround for this, usually involving diodes in series with the GND or the 5V power line to the WS2812B. But in my case I was getting the opposite effect, as if the threshold was a lower voltage than Vdd (3.3V) /2 = 1.65V

    Anyway…

    I checked the width of the other pulses being generated by the SPI and found that only the first pulse was this length and all other pulses were 450nS (actually 444.4ns but my analyser can only resolve to the nearest 10nS), so I concluded that this effect was being caused by the MCU hardware setting up the MOSI signal in advance of the transfer starting.

    Normally this would not be a problem when using conventional SPI, as the data is clocked using a separate signal, and is only happening because I’m using the SPI hardware for a reason other than which is was designed to be used; so I don’t blame ST for building defective hardware ūüėČ

     

    The workaround for this is actually very simple. An additional byte of 0x00 ( 00000000″ ) was added to the start of SPI data buffer, so that the first LED pulse is actually in the second bye of the transfer.

    I also noticed that occasionally the STM32 hardware seemed to leave the MOSI signal at logic 1 after the end of the transfer, even though the last binary bit of the transfer in this protocol is always a zero. This causes a problem, because the WS2812 protocol requires that its Data In, be logic low for 50uS prior to each transfer to act as a Reset signal. The fix for this was also to append another byte of 0x00 to the end of the transfer.

     

    Having got this working within a test sketch, I rewrote it as a library which replicated the Adafruit NeoPixel library API as closely as possible.

    I also did some speed optimisation by replacing the function that calculates the SPI bit pattern, with a lookup table that converts a single colour channel (RGB 8 bit value) into the 24 bit encoded pulse-train needed for the SPI.

     

    But one thing thing was still troubling me, as although I was using DMA to send the SPI data, the existing Arduino STM32 (LibMaple) SPI function dmaSend() is “blocking” (aka synchronous). So that the code execution effectively has to wait until the DMA is complete, before the next set of LED data can be constructed.
    To overcome this, I modified dmaSend() to make a new function called dmaSendAsync(), which returns immediately after the DMA transmission of data has started, and in case the code to construct the next set of LED data completes before the current asynchronous transfer has finished, I took the blocking code from the end of dmaSend and put it into the start of dmaSendAsync and added a static flag to the function so that the blocking code (which waits for DMA completion), is only run if a DMA transfer has been has previously been started.

    Just replacing dmaSend with dmaSendAsync however, would not work correctly, because the Arduino sketch code could update the buffer of data that was currently being sent to the LED’s via DMA and cause unexpected results. To address this problem I added a double buffer system, so that the data buffer that functions like setPixelColor() interact with, is different from the buffer being sent to the LEDs; and the buffers are swapped as part of the library’s show() function – which sends the data via SPI.

    This is all very standard and easy to implement in the code, but when I ran the test / example sketch, I found that some visual effects, specifically colorWipe() function were not working as expected, and caused to flash the LED’s in a very strange way.

    Initially I presumed I must have made a mistake with how I handled the double buffering, because the problem went away if I switched back to single buffering, (with some added delays), but after exhaustive examination of the data and using the logic analyser to see what was actually being sent, I finally realised that the visual effects created by functions like colorWipe() are additive.

     

    void colorWipe(uint32_t c, uint8_t wait)
    {
       for(uint16_t i=0; i<strip.numPixels(); i++)
       {
          strip.setPixelColor(i, c);
          strip.show();
          delay(wait);
       }
    }

    Where this function effectively does the following:-

    Set pixel 1 to Colour X
    Send data to all LEDs

    Set pixel 2 to Colour X
    Send data to all LEDs

    Set pixel 3 to Colour X
    Send data to all LEDs

    Set pixel 3 to Colour X
    Send data to all LEDs

    Which produces the following effect

    ___________
    X__________
    XX_________
    XXX________
    XXXX_______

    etc

     

    But if there are 2 buffers, (both initially empty) what the code would do is…

    Set Buffer 1, pixel 1 to Colour X
    Send data to all LEDs

    Set Buffer 2 pixel 2 to Colour X
    Send data to all LEDs

    Set Buffer 1 pixel 3 to Colour X
    Send data to all LEDs

    Set Buffer 2 pixel 4 to Colour X
    Send data to all LEDs

     

    Which produces this effect

     

    ___________
    X__________
    _X_________
    X_X________
    _X_X_______

     

    Unfortunately the only way around this problem is to copy the contents of the last updated frame buffer to the other frame buffer. But at least this can be done during the DMA transfer if buffer pointers are exchanged each time

     

    // Sends the current buffer to the leds
    void WS2812B::show(void) 
    {
      SPI.dmaSendAsync(pixels,numBytes);// Start the DMA transfer of the current pixel buffer to the LEDs and return immediately.
    
      // Need to copy the last / current buffer to the other half of the double buffer as most API code does not rebuild the entire contents
      // from scratch. Often just a few pixels are changed e.g in a chaser effect
      
      if (pixels==doubleBuffer)
      {
    	// pixels was using the first buffer
    	pixels	= doubleBuffer+numBytes;  // set pixels to second buffer
    	memcpy(pixels,doubleBuffer,numBytes);// copy first buffer to second buffer
      }
      else
      {
    	// pixels was using the second buffer	  
    	pixels	= doubleBuffer;  // set pixels to first buffer
    	memcpy(pixels,doubleBuffer+numBytes,numBytes);	 // copy second buffer to first buffer 
      }	
    }
    

     

    At the time of writing I’m using memcpy to copy the buffers, but this may not be the most efficient way to do this, as memcpy may be doing single byte copies, where as 32 bit copies would be faster.

    So I’m considering padding the frame buffers to 4 bytes, by adding bytes as necessary, depending on the number of LEDs. Currently each buffer is NUM_LEDs times 3 + 1 start byte + 1 end byte, e.g. 30 LEDs takes 272 bytes

    The other thing that makes the code run slower in some places than the bit-banged version is the need to use the lookup table to copy the 3 bytes per colour into the frame buffer.

     

    void WS2812B::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
     {
       uint8_t *bptr = pixels + (n<<3) + n +1;
       uint8_t *tPtr = (uint8_t *)encoderLookup + g*2 + g;// need to index 3 x g into the lookup
       
       *bptr++ = *tPtr++;
       *bptr++ = *tPtr++;
       *bptr++ = *tPtr++;
    
       tPtr = (uint8_t *)encoderLookup + r*2 + r;
       *bptr++ = *tPtr++;
       *bptr++ = *tPtr++;
       *bptr++ = *tPtr++;   
       
       tPtr = (uint8_t *)encoderLookup + b*2 + b;
       *bptr++ = *tPtr++;
       *bptr++ = *tPtr++;
       *bptr++ = *tPtr++;
     }
    

    I’ve tried to optimise the code by using sequential pointer reads and writes with increment, however it was still 60% slower than the bit-banged code, which simply needs to write the RGB values straight into the frame buffer

    Moving the LUT from flash to RAM has improved the speed by about 30%, so that setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) now takes 1224nS to execute (including the call overhead, rather than 1642nS. The bit-banged version, which just sets 3 bytes in the frame buffer takes 948nS, so is still 28% faster even with no optimisation.

    There may be further optimisations that can be performed on this code to increase the speed, possibly using the strategy described by @stevestrong on the STM32duino.com forum http://stm32duino.com/viewtopic.php?f=16&t=2184#p29511

    But that will have to wait for a day when I have more free time to allocate to this.

     

    Overall, I think the jury is still out, about whether using SPI and DMA rather than simply bit-banging the data is the best approach.

    If the bit-banged method could be made to work without disabling the interrupts during the entire duration of the show() function, it would probably be fine for most simple effects, and may even work faster in a lot of cases.

    However, just disabling interrupts when each High / Low waveform is created, and re-enabling the interrupts between data bits, would technically break the WS2812B’s spec, as the Low period would be variable and almost always longer than is technically correct.

    Also for effects which required a lot of processing for each pixel, using DMA would potentially increase the frame rate

    If I get time I’ll also publish a bit-banged version, and in the mean time anyone interested in trying the code can download the latest version of the Arduino STM32 repo

    https://github.com/rogerclarkmelbourne/Arduino_STM32/

    Or look at the library code here

    https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F1/libraries/WS2812B

    2 Comments "

    Don’t buy this smartwatch / fitness tracker !

    December 7th, 2016

    Just a quick post about another smartwatch / fitness tracker that I was miss-sold on eBay

    Its title was
    A16 Bluetooth Smart Watch Health Wrist Bracelet Heart Rate Monitor Sports New
    Do NOT buy this watch

    http://www.ebay.com.au/itm/182341391730

     

    It is listed as using the Nordic nRF52832 Bluetooth MCU, but when I opened the watch to see how to reprogram it, I found it contained a Dialog processor

     

    Unfortunately as I had already accepted the item, and given feedback in eBay.
    But as the item was delivered by registered post with a tracking code and I had to sign for it, the vendor knows I received it, so I couldn’t simply pretend it had never arrived (which is sometimes the best option with dodgy vendors as they have to resend or give a refund if you don’t receive the goods)

     

    I have written to the vendor (¬†http://www.ebay.com.au/usr/rsp99998 )¬† to complain, I doubt they care, so I think I’ve just wasted $30 as I bought 2 of them.

     

    But I doubt I will get a good resolution from this.

    14 Comments "

    BBC Micro bit hardware designs are now available on github

    October 21st, 2016

    I think the profile of the nRF51 is about to take a big leap forward, as the previous closed hardware design for the BBC Micro-bit, which has been rolled out around a million school children in the UK, has not been released on GitHub https://github.com/microbit-foundation/microbit-reference-design

    There is a press release http://www.bbc.com/news/technology-37682405  indicating that the micro bit foundation will be encouraging the use of the design throughout the world.

    I am not a lawyer, but the license appears to allow anyone to use these designs.

    So if this is correct, I imagine that a lot of Chinese manufacturers would be interested in producing versions of this, because at the moment, they are only available in the UK and the cost is fairly high (£13)

    Which would be good news if the price was brought down in line with boards like the Arduino Uno, or my favourite STM32 boards.

     

    Update. May 2017

    These reference designs appear to be for a binary compatible nRF51 board not the actual BBC Microbit board as given to students in the UK.

    The board is much bigger and uses an nRF51 module rather than the nRF51822 MCU

     

    No Comments "

    Blackmagic probe problems with a new nRF51822 device revision

    October 6th, 2016

    I know quiet a few readers of the blog are interested in the nRF51822, and use either the Blackmagic probe or OpenOCD to program your devices.

    So I thought it worthwhile to share my experiences today, when I was unable to program a nRF51822QFAA device

     

    To cut to the chase, the device identification in full is the nRF51822QFAAH1.  This appears to be a new revision of the QFAA device (16k RAM 256k flash), which neither the Blackmagic probe or OpenOCD support, as its CONFIG ID code seems to be 0x008F where as the QFAAH0 is 0x0072

    I will endeavor to update my Blackmagic probe repo as soon as I have confirmation via the Nordic developers forum that this indeed the case.

    I’ve also logged a issue on the master Blackmagic probe repo, and will bring this to the attention of the OpenOCD team if confirmed.

     

    In reality, the problem of not being able to program a specific board, has taken a while to quantify, as I had a batch of 40 boards to flash with custom firmware, and the first board I tried seemed to have this issue, so I ended up using a Jlink to flash the boards (which had its own issues, but thats another story).

    Anyway, of the 40 brand new boards I received from a Chinese manufacturer, only 1 seems to contain this new device, so it was sod’s law that it was the first board that I attempted to program.

    And doubly confusing, as I presumed the whole batch had the new device, so I didnt take note of which board would not initially program, So ended up having to retest all 40 again to find it, and confirm that all the other boards contained the QFAAH0 version.

    But thats the way the cookie crumbles some days.

    19 Comments "

    nRF51822 based fitness trackers

    September 20th, 2016

    As regular readers of my blog will know I’m an ardent fan of the Nordic nRF51 (and nRF52) series of Bluetooth Low Energy MCU’s.

    So when I found out that a number of fitness tracker / smart watches, used the nRF51822 and could be easily opened and reprogrammed I was very interested and ordered 2 of them to try.

    Unfortunately soon after I ordered them, it became clear that the model I had ordered would probably not be powered by an nRF51822, and hence started my quest to understand what models of smart watch do, really, use the nRF51.

     

    Firstly, the model number of the watch I ordered was a TW64 – which is where the confusion starts.

    A number of completely different watches are sold as a TW64 but contain completely different processors.

    The ones I ordered, from eBay, had the Quintic QN9021 ( http://www.nxp.com/products/microcontrollers-and-processors/more-processors/application-specific-mcus-mpus/bluetooth-low-energy-ble/ultra-low-power-bluetooth-le-system-on-chip-solution:QN9021)  listed as the main processor, however when I opened mine up, it actually contains a Dialog DA 14850 processor  (http://www.dialog-semiconductor.com/products/connectivity/bluetooth-low-energy/smartbond-da14680)

    Either way my watch unfortunately didn’t contain an nRF51

     

    However searching for “TW64 nRF51822” does find some watches marketed as a TW64 which do contain the nRF51822, which lead me to Shenzhen DO Intelligent Technology Co., Ltd. on Alibaba.

    I contacted them to find out more details and found that all of their smart watch/ fitness trackers use the nRF51822

    Their product numbers are P101,P102,ID100HR,ID105,ID105HR,ID107,ID107HR,ID101HR,ID110HR,ID111HR and ID115HR

    So if you are looking for an nRF51 based smart watch, your best bet is to search using one of those model numbers, and double check the details in the eBay / AliExpress / Gearbest etc listing to confirm it does mention the nRF51822

     

    In the end I decided to buy an ID100HR and a ID107HR, via AliExpres.

     

    When my ID100HR arrived, and I unscrewed the back of the case on the watch, I was pleasantly surprised to find that the watch contained an nRF51822QFAC, which is the 32k RAM version (top of the range for this MCU), and also that the watch has both the 16Mhz main crystal and also the 32kHz low power mode crystal.

     

    With the help of Goran Mahovlic, I can now reprogram this watch using the Arduino IDE and can read from the accelerometer sensor, and write to the display, as well as get input from the button and turn on and off the vibration motor.

    I have yet to investigate how the Silicon labs Si1142, Heart Rate sensor is interfaced to the MCU, but as its I2C, its possible its wired onto the same bus as the Kionix kx022-1020 accelerometer.

    So it should be possible to use this feature of the watch as well.

     

    If anyone wants to give this a try for themselves, please also read my previous postings about programming the nRF51822 using the Arduino IDE and also refer to my latest Arduino for nRF51822  repo on github.

    https://github.com/rogerclarkmelbourne/Arduino_nrf51822

     

     

    20 Comments "

    Running RDWorks on Linux

    August 29th, 2016

    As a matter of interest, I thought I’d see if I could use the RDWorks laser cutter control program on Linux, even though its a WIndows only application.

    Linux add-in called WINE ( https://www.winehq.org/ ) that allows Windows exe’s to be run under Linux.
    However when I tried to install RDWorks using WINE I initially got a load of error messages which implied that loads of RDWorks DLL’s were missing or could not be located.

    I initially thought this was because RDWorks had to run in a specific location, but after movingit to various places on my machine, I found the error messages were a red herring, and the problem was that WINE did not have one of the core Microsoft DLL files.

    The fix for this was to install something called “Wine Tricks” https://wiki.winehq.org/Winetricks and use it to install the missing DLL.
    MFC42.DLL

    With this installed, The RDWorks installer will actually run and install RDWorks under Linux

    However you do not install the USB driver, as the FT232 driver is already installed on most Linux installations.

    Once installed RDWorks does run, but with one strange quirk; the vertical scaling in the design window is incorrect, and you initially get a bed shape that is very tall and narrow.

    So I changed settings for page setting, and 900 x 400 looks good on screen. This setting isnt really important to the laser cutter its self, as its completely ignored even my RDWorks, as you can edit and cut objects outside of the bounds of the laser cutter (as defined in the setup)

    One thing I have not managed to get working yet is the USB transfer to the laser cutter.
    I think the issue is the mapping of the FT232 serial device on Linux to the COM port that RDWorks requires
    The solution is probably that I need to map / link the systems’ serial port to the Wine serial port as described here
    http://g8ogj.org/files/Using%20USB%20se … %20ipb.pdf

    But I have not had time to test this yet.

    An easier option is probably to transfer by LAN, as this works well under Windows and its likely to work on Linux.

    No Comments "

    Mahoney CO2 laser power meter

    August 16th, 2016

    I recently bought a Mahoney laser power meter from “Bell Laser” (www.bell-laser.com , also known as www.2laser.com), to establish whether my “50W” Chinese laser cutter was actually producing anywhere near 50W.
    Read the rest of this entry “

    4 Comments "

    Network aware laser cutter security

    August 4th, 2016

    My Chinese laser cutter has a feature which allows it to be connected to a cabled LAN, but I’m always concerned about attaching random hardware to my home network as sometimes Internet connected devices have a “phone home” feature where they connect to a central server and send back log data, or possibly do other things which you’d rather they didn’t.

    So although my workshop PC is around 5m from my laser cutter, I initially opted to use a USB extension cable to connect the PC to the laser cutter.

    Unfortunately I found that using a long USB cable was problematic as the laser cutter kept disconnecting from the PC, and I’d have to unplug and reconnect the cable, almost every time I sent a job to the cutter.

     

    As my workshop PC is not actually connected to the Internet, I decided it was safe to make a Ethernet crossover cable and connect the PC directly to the laser cutter via cat 5 cable. The cable worked well, and the connection does not drop out, and the cutter control software seems to work in exactly the same way as when communicating via USB.

    As I was still curious about whether the cutter had a “phone home” feature, I decided to install WireShark on the PC and monitor the LAN traffic.

     

    The control unit in the laser cutter is a RUIDA RDC6442G ( http://en.rd-acs.com/products.aspx?TypeId=50097&FId=t3:50097:3 )

    On the control panel, you set the IP address of the laser cutter and also enter the address of a gateway, so I entered the IP of the workshop PC as the gateway IP, and then fired up Wireshark

     

    I was pleased to see, that the laser cutter does not appear to communicate over the LAN at all, unless sent data from the control program (RDWorks) in the PC. I left the machine for several hours and not a single packet was detected.

    This does not completely rule out that the laser cutter may attempt to communicate after an extended period e.g. every 24 hours, but at least it does not start trying to contact the Internet immediately

    The control program RDWorks doesnt seem to access the Internet either, which is also very good news.

     

    The main reason for monitoring the data was for network security reasons, but I had a quick look at the data protocol.

    When RDWorks communicates with the cutter it uses UDP, sending to port 50200 on the cutter, and the cutter sends back UDP data to port 40200

     

    The format seems to be proprietary binary, with RDWorks sending a command packet.

    e.g. This seems to be the initial packet that is always sent by RDWorks

    02:61:d4:89:0d:f7

    to which the RDC6442G  responds with

    c6

    and then sends a reply packet e.g.

    d4:09:0d:f7:8f:a1:09:c3:89

     

    Another example is RDWorks sends

    02:73:d4:89:89:8d

    to which the RDC6442G  responds with

    c6

    and then sends

    d4:09:89:8d:89:89:89:89:ab

     

    When I sent drew a 10mm x 10mm square in RDWorks and sent this to the laser cutter, by pressing the start button, this appears to be the data for this cut (but at lest 5 commands were sent to the cutter before this data was sent, and RDWorks sent a further 411 bytes in the next command

    f9:3e:d2:9b:fa:7a:8b:89:d2:89:70:8f:89:89:89:89:89:89:89:89:89:89:70:0b:89:89:89:89:89:89:89:89:89:89:70:0f:89:89:89:c7:99:89:89:89:c7:99:70:d9:89:89:89:89:89:89:89:89:89:89:70:59:89:89:89:c7:99:89:89:89:c7:99:70:8d:89:09:89:09:89:89:89:89:89:89:89:89:89:89:70:0d:89:42:8d:89:89:89:85:93:c9:d0:39:89:5b:91:d0:bb:89:5b:91:d0:49:89:af:bb:d0:cb:89:af:bb:d0:3d:89:af:bb:d0:bf:89:af:bb:d0:3f:89:af:bb:d0:b1:89:af:bb:c4:8f:89:89:89:89:89:89:c4:49:89:8b:70:db:89:89:89:89:89:89:89:89:89:89:89:70:5b:89:89:89:89:c7:99:89:89:89:c7:99:70:69:89:89:89:89:89:89:89:89:89:89:89:70:eb:89:89:89:89:c7:99:89:89:89:c7:99:c4:ab:89:70:dd:89:89:89:89:89:89:70:dd:09:89:89:89:89:89:70:5d:89:89:89:89:89:89:70:5d:09:89:89:89:89:89:7a:0b:89:89:89:89:89:89:89:89:89:89:7a:89:89:7a:09:89:fc:89:89:fc:09:89:fc:8b:0d:a3:31:95:49:8d:e3:1d:81:a9:fc:0b:89:89:89:89:89:89:89:89:89:89:fc:8d:89:89:89:c7:99:89:89:89:c7:99:fc:8f:89:89:89:89:89:89:89:89:89:89:fc:0f:89:fc:0d:89:09:89:09:77:77:77:39:f9:89:89:89:c7:99:e4:89:70:e9:89:70:1b:89:89:89:89:89:89:89:89:89:89:70:1f:89:89:89:c7:99:89:89:89:c7:99:70:2b:89:89:89:89:89:89:89:89:89:89:70:ad:89:70:81:89:09:89:09:77:77:77:39:f9:89:89:89:c7:99:c4:09:09:c4:8b:89:c4:09:b9:c4:09:99:c4:09:1b:42:8b:89:89:85:93:c9:d0:09:5b:91:d0:8b:5b:91:d0:0d:af:bb:d0:8f:af:bb:d0:0f:af:bb:d0:81:af:bb:d0:9b:89:89:89:89:89:d0:1b:89:89:89:89:89:c4:0b:05:82:89:89:89:89:89:89:89:89:09:9f:a2:89:89:89:c7:99:89:89:89:09:9f:04:09:9f:a2:89:89:89:89:89:89:89:89:8b:a5:04:09:9f:a2:89:89:89:c7:99:89:89:89:0b:cb:04:09:9f:a2:89:89:89:89:89:89:89:89:8d:d1:04:09:9f:a2:89:89:89:c7:99:89:89:89:0d:e7:04:09:9f:a2:89:89:89:89:89:89:89:89:0f:8d:04:09:9f:a2:89:89:89:c7:99:89:89:89:81:93:04:09:9f:a2:89:89:89:89:89:89:89:89:01:b9:04:09:9f:a2:89:89:89:c7:99:89:89:89:83:cf:04:09:9f:a2:89:89:89:89:89:89:89:89:03:d5:04:09:9f:a2:89:89:89:c7:99:89:89:89:85:fb:04:09:9f:a2:89:89:89:89:89:89:89:89:87:81:04:09:9f:a2:89:89:89:c7:99:89:89:89:07:97:04:09:9f:a2:89:89:89:89:89:89:89:89:99:bd:04:09:9f:a2:89:89:89:c7:99:89:89:89:19:c3:04:09:9f:a2:89:89:89:89:89:89:89:89:9b:e9:04:09:9f:a2:89:89:89:c7:99:89:89:89:1b:ff:04:09:9f:a2:89:89:89:89:89:89:89:89:1d:85:04:09:9f:a2:89:89:89:c7:99:89:89:89:9f:ab:04:09:9f:a2:89:89:89:89:89:89:89:89:1f:b1:04:09:9f:a2:89:89:89:c7:99:89:89:89:91:c7:04:09:9f:a2:89:89:89:89:89:89:89:89:11:ed:04:09:9f:a2:89:89:89:c7:99:89:89:89:93:f3:04:09:9f:a2:89:89:89:89:89:89:89:89:95:99:04:09:9f:a2:89:89:89:c7:99:89:89:89:15:af:04:09:9f:a2:89:89:89:89:89:89:89:89:97:b5:04:09:9f:a2:89:89:89:c7:99:89:89:89:17:db:04:09:9f:a2:89:89:89:89:89:89:89:89:a9:e1:04:09:9f:a2:89:89:89:c7:99:89:89:89:29:f7:04:09:9f:a2:89:89:89:89:89:89:89:89:2b:9d:04:09:9f:a2:89:89:89:c7:99:89:89:89:ad:a3:04:09:9f:a2:89:89:89:89:89:89:89:89:2d:c9:04:09:9f:a2:89:89:89:c7:99:89:89:89:af:df:04:09:9f:a2:89:89:89:89:89:89:89:89:2f:e5:04:09:9f:a2:89:89:89:c7:99:89:89:89:21:8b:04:09:9f:a2:89:89:89:89:89:89:89:89:a3:91:04:09:9f:a2:89:89:89:c7:99:89:89:89:23:a7:04:09:9f:a2:89:89:89:89:89:89:89:89:a5:cd:04:09:9f

     

    I don’t think there is any point in further investigation of the actual protocol itself as RDWorks is free and although is Windows only, it appears to run OK under Wine on Linux.

     

    Overall, although I would not connect the laser cutter to my internal LAN because of the safety implications of any computer on the LAN sending the command to start the laser cutter running, I think that from a network security standpoint it seems relatively safe.

    If absolute network security is required a cheap wifi / wired router running OpenWRT or DDWRT could by placed between the laser cutter and the rest of the network to limit traffic to just UDP and ports and 40200 50200 and limit which IP addresses the laser cutter is allowed to communicate with.

    Or just use a dedicated PC with no other network connections, like I do.

     

    4 Comments "

    Changing the language setting on a Chinese laser cutter

    August 2nd, 2016

    Just a quick post in case it helps anyone who has the same problem with their newly purchased Chinese laser cutter, where the menu language is set to Chinese (probably “Simplified Chinese”)

    The original display looks like this. Note all the words are in Chinese

    laser_original_display

    If you push the button labelled “Z/U” it opens the main menu, which is also in Chinese

     

    laser_chinese_menu

     

    If the machine has English set as the language, the menu would look like this.

    laser_english_menu

    So what you need to us press the down arrow, below the “Z/U” button, until the button at the top of the second column of buttons is selected.

    laser_chinese_menu_select_language

    This displays the language selection screen, where you need to select the third option down and press Enter.

    laser_chinese_menu_select_language_select_english

    If English was selected, the screen would look like this

    laser_english_menu_language

     

    Once English is selected, the text on the main screen will be in English and you can confirm this by pressing the “Z/U” button to enter the menu.

    BTW, Pressing “Esc” exits the current menu.

     

    PS. Someone else may well have already documented how to do this but I couldn’t find how to do this when I searched the web, so my method to figure out what was on the menu’s was to guess what words would be displayed e,g, “Language” and then use Google Translate to show be the Simplified Chinese equivalent, then visually compare what was on the menu with the Chinese characters, and fortunately they had called one of the menus “Language” so I was able to match the Chinese characters closely enough to work out which menu it was.

    Annoyingly, inside the language menu, it doesn’t have the language names in latin text e.g. English or French or German etc.

    So I had to google translate “English” to work out which language option

    4 Comments "

    Troubleshooting the nRF51822

    July 15th, 2016

    I’ve had quite a few comments where people are having problems uploading or running sketches on the nRF51822, so as I don’t have time to answer individual questions, I thought it best to try to cover the main reasons that things may not work

     

    Device is not recognised by Blackmagic probe or possibly not by JLink

    Originally I had a lot of issues with Blackmagic probe not recognising the ID code in the nRF51822. When this happens the Blackmagic probe reports the nRF51822 just as ARM cortex M0 rather than nRF51822

    If you have this issue with my latest repo, please let me know, as the only option is to manually read the ID code and send it to me, so I can add that code to the list in the firmware and then rebuild the Blackmagic probe firmware.

    The main problem is that Nordic do not keep an updated document of what ID codes they use, and most of the codes have been gathered and compilated by various users from various sources.

    However I think this situation has now stabilized and Nordic have not released any new ID codes recently

    This is not so much of an issue with JLink as you have to tell JLink which device you are programming,but this is not an option with the Blackmagic probe firmware.

     

    nRF51822 chip is read protected / locked

    This problem can occur if you are using a module which is pre-flashed with some firmware already.

    In my case the  modules I bought from Wireless-tag (http://www.wireless-tag.com/index.php/product/9.html) , specifically http://www.wireless-tag.com/index.php/product/dis/25.html had this problem

    I hoped the my JLink could disable the read protection, as this is a menu option in JFlash, however the option is greyed out and JFlash gives some erroneous error message when you connect, about an issue with the RAM

    This problem can also be caused if you use JFlash to “Fill with zero”, as I found out by accident one day

    Eventually I found a solution to this, on Nordic’s website https://devzone.nordicsemi.com/question/631/cannot-recover-with-nrfgo-could-not-read-ahb-ap-id-could-not-connect-to-target/

    And the solution is to manually write commands into 3 of the nRF58122’s registers

    In JLInk the commands are

    w4 4001e504 2
    w4 4001e50c 1
    w4 4001e514 1

    And GDB has an equivalent write command

    After these registers are changed, it will cause the whole MCU to be erased and you should be able to connect via JFlash or Blackmagic probe without an errors and upload your new firmware

     

    S130 softdevice has not been flashed into the bottom of flash (0x00000)

    The bluetooth API functions provided by Nordic some in the form of a “Softdevice”

    The best way I can describe a Sottdevice is a cross between a bootloader and a dynamic link library.

    The code for all the BLE functions is in this closed source Softdevice, and the sketch makes calls into the Softdevice in order to access that functionalityAdditionally, the Sketch code is compiled to run at address 0x1c000 (for the V9 Soft device) – Note the latest version of the Softdevice, at the time of writing, is V2.0.1 from SDK V11, and is slightly smaller and expects the sketch (application) code to be at 0x1B000 – so make sure you download the old SDK V9 and use the S130 softdevice from that SDK.Basically the Softdevice is installed at address 0x00000 and when the MCU starts up, it runs a small amount of Softdevice initialisation code, and then the Softdevice passes control to the application sketch at 0x1B000, the Softdevice also attaches to some interrups to do its own functions, but all other iterrupts are forwarded to the application, as the softdevice inspects the applications (sketches), interrupts vector table and calculates the address to call inside the application code for each interrupt.Consequently unless you have installed the S130 softdevice into address 0x00000, the sketch will not run because it will be installed at 0x1C000 with jibberish in the flash at addresses 0x00000 to 0x1BFFF, which the MCU will run at startup.
    I suppose if the flash from 0x00000 to 0x1BFFF was filled with nops this may work, but there are better ways of running without the softdevice e.g. change the linker script to position the sketch at 0x00000 and change the upload script to make sure its flashed at 0x00000Overall, just make sure the correct version of the Softdevice is flashed at 0x00000

     

    Module does not have the 32Khz RealTime Clock crystal

    If you installed the Softdevice and uploaded the sketch code and nothing works, e.g. including a “Blink” sketch, the reason is probably that your “no name” board does not have a 32Khz cystal oscillator

    My current repo only works with modules that have the RTC.

    I am working on an updated version that works without the RTC, but if you have a module that omitts this, you have 4 options

    1. Solder a 32khz crystal and the 2 capacitors to the correct pins on your module (I did this with a Wireless-tag module)
    2. Use Mbed instead of Arduino
    3. Hack the latest version of the RedBearLabs Arduino repo to work with your board (this is what I’m now working on)
    4. Wait for me to release my new version

     

    Windows Blackmagic Probe driver problems

    The BMP drivers work fine on Windows 7 but I have not tested them on Windows 8, or 8.1 or 10.

    I have had a report that they may not work on W10 because of signing issues, which is strange as W7 requires signed drivers and they work fine.

    If you have problems with driver signing on W10, just google for running unsigned drivers and there are some work-arounds, but its generally not recommended to run Windows permanently in a special mode to allow unsigned drivers, as it could be a security issue.

     

    Other ways to work out whats going wrong

    If you are not sure if you code is being uploaded, I’d recommend you powercycle your board and then reconnect and read back the flash from 0x1c0000 for about 1k and compare with the first 1k of the binary compiled by the Arduino IDE

    If they are different, then you have not really uploaded, and with the Blackmagic probe this normally indicates that it has not recognised the MCU as a nRF51822 and is treating it as a normal ARM cortex M0 in which case I don’t think it can correctly erase the flash before programming it.

    If you can’t connect via SWD, one cause can be transposed SCK and SDIO lines, so try swapping them over

    JLink will not connect unless you feed 3.3V from the target board back into the “sense” input

    With BMP its often best to manually run GDB and connect to the BMP and then connect to the nRF51822. See this post about connecting via GDB

    https://github.com/blacksphere/blackmagic/wiki/Useful-GDB-commands

     

    I’m afraid I do not have much free time to answer individual questions about installation or other problems, but feel free to post in case your questions or solutions help out others

    2 Comments "

    Replacement 3D printed CO2 laser bracket

    July 2nd, 2016

    When I bought by cheap “50W” Chinese laser cutter, I was alarmed to see that the brackets holding the laser in place were just bits of bent galvanized steel, packed around with a large amount of black rubber in order to get the laser into alignment.

    And when I needed to remove the laser to clear some air bubbles that had formed in the cooling water, I found it virtually impossible to realign the laser into its original position.

    My solution was to design some custom laser brackets which I could 3D print on my old MendleMax 3D printer.

    The brackets fit a 2 inch diameter tube, with 2mm padding rubber used inside the bracket.

    Height is adjustable, but was designed to work with my machine.

     

    laser_tube_bracket

     

    laser_tube_brackets_photo

     

    The design was done in OpenSCAD, however the code needs to be tidied up before I publish it, but I’m happy to share the STL file

    Download by right clicking and saving the contents of this link laser_tube_bracket.stl

    Note. You need to remove the .txt from the end of the file. I only added that additional (.txt) extension so that systems would download the file, as the .STL file extension is also used for security certificates and is sometimes blocked.

    No Comments "

    Reprogramming the Dash Robotics Kamigami – Part 1

    June 28th, 2016

    As regular readers will know, I’m a fan of the Nordic nRF51822 Bluetooth MCU, as it can be programmed developed using Open Source tools.

    So when I saw the Dash Robotics Kamigami at Bay Area Maker Faire in May, and spoke to their hardware engineer Dwight Springthorpe, who confirmed that this innovative educational toy used the nRF51822, I took the plunge and bought one on the spot – at the special show price ūüėČ

    See http://kamigamirobots.com/

     

     

    Dwight told me that Dash Robotics were interested in people developing for this product using the Arduino IDE, so I hoped I could develop an Arduino library to allow the various peripherals of the Kamigami to be programmed by the Arduino IDE, or possibly develop using mbed.org

    When I initially got in touch with Dash via email, they were reticent at providing me with any information about the hardware. So I set about reverse engineering the Kamigami.

    Luckily a few days later I was able to get in touch with Dwight directly via email, and he has since provided me with some technical details.

     

    As I first step I had to solder a 4 pin header to the empty header points on the board and hook it up to a SWD programmer and see if I could reprogram the nRF51822.

     

    kamigami_swd_pins

     

    The connections are labeled on the silk screen,

    GND = GND

    CLK = SWCLK

    3     = Vdd (3.3V)

    D     = SWDIO

    I hooked this up to a Jlink. (remember you need to connect the 3V pin to the Jlink or it won’t detect the nr51822 as being connected.

    Before I overwrote the existing firmware, I thought it prudent to see if I could read back the existing firmware, in case I needed to re-install the existing firmware, while reverse engineering the hardware peripheral connections, and to my pleasant surprise I found that I was able to read out the all of the Flash memory, as the nRF51 had not been read protected.

    kamigami_jlink

     

    So I now had firmware backed up in case I need to a restore.

    At this point, I had intended to possibly poke around the PCB using a multi meter and a scope to try to determine how the peripherals are connected to the nRF51, but I suddenly realised that I could restore the firmware backup onto a more convenient debug platform, namely my WaveShare nRF51822 (http://www.waveshare.com/nrf51822-eval-kit.htm)

     

    ble400-4_2

    This board has a slightly different MCU, as it has the better QFAC variant with 32kb of RAM instead of the QFAA on the Kamigami but apart from that the MCU is identical. The other difference between the Kamigami PCB and the Waveshare is that the Kamigami doesn’t have the 32kHz RTC oscillator crystal (and the Waveshare does). This can make a big difference to the nRF51 startup code, and also its operation, because firmware written for boards with the 32kHz osc, don’t normally work on boards that omit this oscillator.

    Fortunately the reverse is not generally true, and after flashing the firmware backup to the Waveshare board, I was able to connect to it using both Kamigami iOS app.

    I selected the “Drive” option in the app, and twiddled the joystick that controls the 2 motors, and I noticed that some of the LED’s on the Waveshare board began to light up.

    http://www.waveshare.com/img/devkit/accBoard/BLE400/BLE400-size.jpg

    Specifically, the LED’s on pins P18,P19,and P20. All the pins seemed to be driven via PWM, as the LED intensity could be adjusted. P18 and P19 seem to get lit when the robot would be moving forward, and P20 was lit when the robot would be going backwards.

    This seemed an odd arrangement, so I checked whether and of the other adjacent pins had PWM on it when moving the virtual joystick in the app, and found that P17 seemed to modulated when the robot would be going backwards.

    i.e

    P0.17 is left motor reverse control

    P0.18 is the left motor forward control.

    P0.19 is right motor forward control

    P0.20 is right motor reverse

     

    Hooking a scope up to these pins, revealed that they were modulated at a clock frequency of just 64Hz, and that the joystick control has slightly odd mapping, in that For Example, 100% PWM is delivered to the right motor, not when the joystick is fully forward in the middle, but is actually when the joystick is over hard to the middle left, when the robot is being commanded to turn left – not that this important information at the moment, but may come in handy later when programming some new firmware.

    Incidentally, the motor driver IC’s appear to be GPY0067A, but I can’t track down a datasheet it… Not that this is particularly important as I’m pretty sure I know how to control the motors.

    The next thing I looked for was what controlled the 3 tri-coloured LED’s (which are wired in parallel), and a quick visual inspection of the board, revealed that the LEDs were on pins P0.5, P0.6 and P0.7, and playing with the App isolated that

    P0.5 = Blue channel

    P0.6 = Green channel

    P0.7 = Red channel

    Looking at these on the scope was also interesting, as the App just seems to have each channel, either on or off, but the scope showed that the LED’s are actually being driven with 64Hz PWM (like the motors), so it would be possible to get the LED’s to be any colour from black to white, not just the 6 options in the “Games” section of the App.

     

    Moving on to the inputs.

    The ambient light detector seems to be attached to P0.02, as grounding this pin though a resistor changed the value displayed in the App.

    The App displays the Battery level, but I have not been able to establish if this value is taken by reading the a pin, or whether its just a calculated value, which goes down depending on the amount of motor and LED usage.

     

    The Kamigami also has a 6 axis IMU, with 3 accelerometers and 3 gyros. I was unable to read the markings on the IMU chip, so I emailed Dwight and he told me it is an ST LSM330.

    I’m fairly sure that its connected via SPI, but I have not confirmed this with Dwight and I have not tried to communicate with it yet.

    Its actually a real shame that Dash opted to use a IMU without a compass (magnetometer), as in my experience the outputs from the gyros and accelerometers are not especially useful, as they are subject to noise and drift which makes them useless for inertial navigation. Where as the magnetometer always lets you know which way up it is and where north is.(Assuming it has been correctly calibrated in the first place)

     

    Developing using mbed

    Although I have an Arduino core that works with the nRF51822, I know it doesn’t work unless the hardware has the 32kHz RTC crystal, and the Kamigami board doesn’t have this.

    However there is an mbed platform for an nRF51822 module without 32kHz crystal –¬† for the¬†HRM1017 (https://developer.mbed.org/platforms/mbed-HRM1017) , that can be used as an equivalent platform.

     

     

    More to follow…

     

     

    No Comments "

    Chinese laser dust seals

    June 3rd, 2016

    Just a quick post about keeping the dust out of laser cutters

    Australia is a very dry dusty country, and dust is a major problem for me with the laser cutter. If dust gets on the mirrors or lens, it gets heated up by the laser which then damages (spot burns) the mirror or lens

    My machine, like most, has a large extractor fan in the rear of the machine, which sucks air out.

    Air is drawn into the machine though any opening in the case, including the laser cabinet, but I saw no reason for air, and therefore dust, to be drawn though that part of the machine.

    The simple and cheap solution is to buy household draft proofing strip from the local hardware store, and stick it where the door to the laser cabinet abuts the cabinet.

     

    laser_cabinet_dust_seals

     

    This worked best in the left of the picture, where the door presses directly into the foam strip.

    It worked slightly less well at the top of the picture as the glue on this cheap draft excluder was not strong enough to prevent it being pushed downwards.

    Nevertheless, it still provides a much better seal than there was before, and as you can see in this photo, there is no dust at all. And I promise I have not just cleaned it before taking the photo.

    I have cleaned it, but not for months, as hardly any dust gets in.

     

    2 Comments "

    Arduino on the nRF51822 Bluetooth Low Energy microcontroller

    November 22nd, 2015

    This is the first in a series of posts about programming the Nordic Semiconductors nRF51822 Bluetooth low energy micro-controller using the Arduino IDE. The post is a big one as it describes the entire hardware and setup process.

     

    The board I’m using can bought bought on eBay, AliExpress or Amazon for well under $10

    (Update 20th Oct 2016. I found who actually makes these module. See  http://www.hyyunjia.com/product/html/?14.html  however they are only available via companies like WaveShare and various other vendors on eBay and AliExpress etc)

    nrf51822 module

    The board does not have either USB or an onboard serial based bootloader, so at least initially, it has to be programmed using an external SWD programmer.

    I’m currently using a Maple Mini STM32¬†board as a programmer

    MapleMini

    By programming¬†it with a custom version of the Black Magic Probe firmware (more on this later), but any SWD compatible¬†programmer should be able to program this device, as long as the programmer explicitly supports the nRF51822 –¬†One other programmer which I know works is the JLink by Segger.

     

    The Maple Mini is available mainly through eBay and AliExpress for around $5 (http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR0.TRC0.H0.Xmaple+mini+stm32.TRS0&_nkw=maple+mini+stm32&_sacat=0 ) and you will also need a USB to serial converter to program it, like this one

    http://www.ebay.com/sch/i.html?_odkw=usb+serial+cp2102&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.Xusb+serial+6+pin.TRS0&_nkw=usb+serial+6+pin&_sacat=0  or any USB to serial that supports 3.3V devices.

     

     

    Although not essential, its a lot easier to connect the nRF51822 RF module if you use a “Motherboard” like this one, which are also available on eBay and AliExpress etc, for around¬†$12 (USD) (without the radio module)

    nrf51822 motherboard

     

     

    The main reason that you should consider buying this board, is that the RF module, uses pin size and spacing which is not commonly used on other development boards, i.e the pins are not 0.1 inch apart, and the pins are shorter and thinner than used on Arduino shields etc.

    However if you are happy to solder some wires to the module, you can save yourself at least $10, which is what I’ve done as I’m still waiting for my Motherboard to arrive.

     

    Anyway, enough of the hardware you’ll need…

    What software is required.

    The first thing you’ll need, if you don’t already have it, is a copy of the Arduino IDE. Currently the only versions of the IDE that I’m supporting are 1.6.4 and 1.6.5

    Once you have installed the Arduino IDE you need to add either the Arduino Due or Arduino Zero board using the  Boards Manager. The reason this is currently required, is to install the ARM compiler and not for the actual Due or Zero. At a later date I will make a JSON file so that the nRF51822 can be installed without needing to install the Due, but at the moment this is the workaound you will need to use.

    The next thing you need to do is download the third party core files from github https://github.com/rogerclarkmelbourne/nRF51822-Arduino/tree/S130_corelib, specifically this zip file https://codeload.github.com/rogerclarkmelbourne/nRF51822-Arduino/zip/S130_corelib

    Next, go to your Arduino sketches folder and if there isn’t already a hardware folder, make a folder called hardware

    Unzip it, and copy the RBL folder from inside /arduino-1.6.x/hardware into your newly created hardware folder, and restart the Arduino IDE

    Now under the boards manager you will have a new board “Generic nRF51822”

     

    Now to make yourself a SWD programmer from your Maple mini

     

     

    First you will need to download the firmware from github https://raw.githubusercontent.com/rogerclarkmelbourne/blackmagic/master/binaries/blackmagic_maple_mini.bin

    Note.

    In order to be able to send updates to the Blackmagic probe team, I’m probably going to need to maintain a direct fork of their master version.

    In which case I will move the version with working binaries to

    https://ww.github.com/rogerclarkmelbourne/blackmagic_archive_version

     

    And also on Windows download the Flash Loader from STM

     

    http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/flasher-stm32.html

     

    Connect the USB Serial to the Maple mini by RX <–>TX and using GND and Vcc to GND and 3.3V on the USB to serial connector.

    You also need to connect the Boot1 pin to gnd on the maple mini during programming

    Then press and hold the button at the end of the Maple mini and then press and release the reset button (this will put it into serial upload mode)

    Then use the STM Flash loader to upload the binary file to the Maple mini.

    Once its been flashed, connect the Maple mini via its USB connector to your PC and it should be detected as 3 new USB devices.

    On windows you will need to install the drivers for these, by downloading http://www.blacksphere.co.nz/downloads/bmp_driver_20130819.zip and unziping, then open the device manager and select each of the 3 unknown usb devices in turn and select update driver software, then browse to the folder you have just unziped and allow windows to install the drivers.

    Note in the Windows device manager, which new USB device is shown as the GDB server, as you need to select that COM port number in the Arduino IDE to upload.

     

    To connect the Maple mini to the nRF51822, you need to connect the following pins

    For the SWD programming of the module use

    Pin 6 -> SCLK on the nRF51822 or on the JTAG connector on the motherboard

    Pin 7 -> SDO on the nRF51822 or on the JTAG connector on the motherboard

    For USB to serial, you can use these pins on the Maple mini

    Pin 8 -> P0.09

    Pin 9 > P0.11

    GND -> Gnd on the nRF51822 or Motherboard

     

    You can use the USB to Serial that is on the Motherboard instead of the Maple mini, in which case don’t connect pins 8 and 9

     

     

    If you are not using the motherboard or want to power everything from the Maple mini, you will also need to connect

    Vdd to Vdd (either on the nRF51822 or the Motherboard)

     

     

     

    Finally…

    open an example sketch like Blink and upload, and if everything is working, you should see a LED blinking on the Motherboard.

    If you won’t have a motherboard, you’ll need to connect a LED to pin P0.15, as this is currently the mapping that I’ve inherited from the RebBearLab files.

    240 Comments "

    GD32F103: A STM32F103 on steroids!

    September 3rd, 2015

    The world of the STM32 continues to get more interesting, with the recent availability of micro-controller boards based on the GigaDevices GD32F103. These devices have a quoted operating frequency of 108MHz, but as I will demonstrate, these boards also seem to work fine at 120Mhz.

    I first became aware of a GD32F103C board being available on TaoBao.com, via a posting on www.stm32duino.com by @jackson009 about a month ago.

    I did some research and discovered that GigaDevices have licensed the design of the STM32F103 from STM, and produced an enhanced version of the STM32F103.

    (Update. Nov 18th 2015. When I published this article in September 2015, it appeared as if GigaDevices were a “strategic partner’ of STM. See¬†http://www.eettaiwan.com/STATIC/PDF/201507/GigaDevice.pdf , however this has now been clarified by STM in a letter to Olimex, indicating that that STM have not licensed the STM32 core to Gigadevices

    So it appears that the GD32 has been designed by Gigadevices to be pin and generally register compatible with the STM32)

     

    The GD32F103 has a maximum quoted clock speed of 108MHz, rather than the 72Mhz on the STM32F103, they also have a number of other changes. However the main improvement seems to be the faster clock speeds.

    I managed to get some GD32F103C8 boards from TaoBao, (via YoyBuy.com) about a week ago and set about trying to use them with the existing STM32 core.

    Initial results were good. It was possible to flash the board using a USB to Serial adaptor, and the blink sketch worked OK, albeit it blinked faster than on the STM32. However Serial didnt work correctly because the clock rate of 108Mhz is 1.5 times faster than on the STM32, so I duplicated the STM32F1 core to make a GD32F103 core and set about investigating the clock settings in order to get the Serial and other timing related things working.

    The first difference I noticed with these GD32F103 boards, is that the crystal is 12Mhz instead of the usual 8Mhz used on STM32 boards. Actually STM32 boards could use 12Mhz crystals but generally 8Mhz ones seem to be used on all STM32 boards I’ve seen on eBay and AliExpress.

    The STM32 (and GD32) have a Phase Locked Loop (PLL) that multiplies the crystal oscillator frequency to become the master clock frequency. The crystal circuit is called the High Speed External oscillator or HSE for short. On the STM32 the normal setting for the PLL is to multiply the 8Mhz by 9 times to give 72Mhz, but as the crystal on the GD32 board is 12Mhz, the 9 times multipler gives 108Mhz – which is the maximum quoted operational speed of the GD32.

    Looking at the other clock controls, the peripheral clocks APB1 and APB2 are quoted as being able to operate at 54MHz and 108Mhz respectively, so the prescalers (dividers) did not need to be changed for the board to operate at 108Mhz.

    However at 108Mhz, the USB would not function. This is because the USB prescaler on the STM32 @ 72Mhz is set to 0x00 which gives a prescale value of 1.5 and hence a USB clock of the required 48MHz, and with the GD32 main clock at 108Mhz, the USB clock would be running at 72Mhz not the required 48Mhz.

    On the STM32, there is just 1 binary bit to control the USB prescaler, with value of 1.5 x or 1 x, which means that the only clock frequencies that will allow USB operation (48Mhz clock) are 72Mhz and 48Mhz.

    However on the GD32, there is an additional bit (23) so that there are 4 USB prescaler options, 1, 1.5, 2 and 2.5, which allows for higher clock speeds to be used while still allowing USB.

    But… And its a bit but… If you do the maths,¬† to use the 108Mhz clock frequency, you need a USB prescaler value of 108/48 = 2.25,¬† But there isn’t a matching USB prescaler option ūüôĀ

    Which strikes me as being very odd.

    The new USB prescaler values of 2.0 and 2.5 allow clock frequencies of 48 x 2 = 96Mhz or 48 x 2.5 = 120MHz.

    I suspect that perhaps GigaDevices thought that they would be able to operate these devices at 120MHz and hence included a prescaler value of 2.5 to cater for this, but perhaps their production was yeild was not good for devices that could operate at 120Mhz over the spec’ed operating voltages and temperature range, so they had to fall back to saying the GD32 could operate at 108Mhz (and fail to point out that USB was not available at that frequency !)

    But like most techie’s I’m always one to push the boundaries, so I thought I may as well set the main PLL to 10 and run the GD32 at 120Mhz and set the USB prescaler to 2.5 so that USB would have the correct clock.

    The GD32’s I have, seem to run fine at 120Mhz, under normal domestic conditions, however initially the USB didn’t work.

    On closer inspection, and after finding a circuit schematic on the web, it became obvious why the USB was not working: it was because the USB DP (D+) line was not pulled high via the normal 1.5k resistor, as the board does not have a resistor on either D+ or D-.  Where as most STM32 boards have 1.5k connected to D+.

    So I fitted an external resistor, and the USB sprang into life.

    I’ve now updated both the stm32duino-bootloader to include a generic-pc13 version which runs at 120Mhz and I’ve also updated the Arduino_STM32 repo to include a generic GD32F103C option. I’ve added a clock speed menu for the GD32, which allows selection of 72,96 or 120MHz, as these are the 3 values that allow USB to work. I could have included 48MHz, but I don’t see a need for this, apart from perhaps in low power applications. I’ve not currently included a 108Mhz option as USB doesnt run at 108Mhz and generally 120Mhz seems to work fine.

    One note with the GD32 core. I understand from reading some docs translated from Chinese, that there are other changes e.g. changes to Timer Capture; but I have not made any changes to the core about this, because at the moment I’m not aware that the core uses timer capture. The only changes that probably need to be made to the EEPROM library and the bootloader, as there appear to be some changes to the flags that indicate when Flash has finished being erased, but at the moment the bootloader appears to work fine, so I will add that to my To Do list for future stability of the code.

     

    (Update. Nov 18th 2015.

    Since posting, this original article I have done some speed comparisons, and the improved clock frequency is not the only improvement. The Flash memory on the GD32 operates without any “wait states” (its known as “Zero wait state”). From what I recall, the STM32 requires 2 or 3 wait states at 72Mhz (don’t quote me on this, but I kown its not zero wait state).

    This change gives an instance performance increase to the GD32 even running running at 72Mhz, which result in a Dhrystone test running with a Vax MIPS speed of 64.41 (@72Mhz) where as the STM32 was showing 48.81 РSee this thread http://www.stm32duino.com/viewtopic.php?f=3&t=76&hilit=dhrystone&start=30#p5466

     

    This is not a terribly scientific comparison, but I think gives a reasonably general indication of the performance differences between the G32 and the STM32

    )

     

     

    In conclusion, the GD32 is an interesting new addition for anyone interested in a cortex M3 device, especially as its very similar to the familiar STM32F103, or anyone interested in more performance than the STM32F103 currently offers.

    6 Comments "

    PCB prototype milling using CNC 3020

    August 4th, 2015

    Making your own PCB prototypes without all the messing around with chemicals sounds like a dream come true. The availability of low cost and seemingly high precision engraving / milling machines could provide the ideal tool for this, but in practice things are not as simple or as good as they appear.

    Ebay has a number of vendors selling desktop CNC mills, commonly called CNC3020. I think the 3020 refers to the size 30 x 20 cm. These are also often referred to as engraving machines, which is probably nearer to the truth than them being a milling machine. Prices start at around $600 (USD).

    If you are thinking of buying one of these please read this whole posting, as there are various bits of important information, which I’ve inserted in what I think are logical places in the description of the unit and how its assembled, configured and used.

    Models

    The first thing to note with these machines, is at the time of writing there are two different variants available, the “old” and the “new” model.
    The “new” / improved model has both different mechanics and different electronics to the “old” model.
    This is an example of the “new” version.

    The key difference in the mechanics seem to be a strengthened gantry on which the “spindle” / milling motor is mounted, with¬† a thick aluminum plate all the way across. I suspect there are other mechanical changes, but its hard to tell from the photos on eBay.

    The other difference is the power supply / motor control unit. The “new” version seems to be housed in a black box, with a sloping front, where as the old version was in a blue box with vertical sides all the way around. The changes appear to be more than just the cosmetics of the box. The PCB’s in this box differ from the ones in the old model as well – however whether they are an improvement over the old version, or just an alternative set of boards, is hard to tell.

    I’ve read a lot of postings about issues of the control unit “missing steps”. This is where the PC tells the control box to move the motor a certain number of steps, but the motor doesn’t turn as much as it is supposed to because the control unit has not passed the correct number of steps onto the motor. I’ve not personally experienced this issue, as it manifests itself with cutting head not moving as far as it should do in any particular direction. However I have found other issue where the cutting head was actually moving slightly too far. More on this later.

    Assembly

    My CNC 3020 arrived as a partial kit, but without a mechanical assembly manual. My unit came with a CD that contained some software and a word doc explaining in pigeon English how to configure the software, again… more on this later.

    I suspect all these units arrive partially assembled, where the motors were not attached to the frame, and their control / power wires were not attached. However its a relatively simple process to attach the motors using the bolts that are supplied, and the unit even came with Hex / Allen keys to tighten up the bolts. You also need to fit the flexible couplers on between the spindle of the motors and the lead screws, but this also just involves doing up some small Hex screws.
    One thing that was slightly odd about my CNC 3020 was that the 3 couplers were not the same design, but all had the same internal diameter for the motor and lead screw shafts. As the unit didn’t come with an assembly manual, I made a guess that the odd one out, of the couplers, should go on the main, back to front / Y axis lead screw motor, however I suspect it does not make any difference.

    Once the motors are bolted on, and you guess which control / power cable goes to each motor, (you can work it out from which cable will nicely reach each motor), you can connect the 4 circular control / power cables to the back of the control unit, and connect the control unit to a PC via a Centronics printer cable.

    Yes… This unit needs your PC to have a old fashioned Centronics / parallel printer port. If your PC does not have one, you are out of luck.

    Buying a USB to Centronics adaptor cable will not work, as the software that is supplied with the unit directly generates square waves on the Centronic port’s pins, using a special Windows driver, and this will not work with a USB to Centronics adaptor.

    Setup

    Anyway, assuming you have an old PC, even a laptop which has a proper Centronics / parallel printer port, you should be OK; but please note, I am also using Windows XP, and I can’t comment on whether Windows 7, or Windows 8 etc, work even if you have a machine with the correct hardware.

    The software that came on the CD with the unit, is “Mach3” except it is a “demo” / limited version, which seems to be quite old.

    Once installed, you have to enter the calibration numbers as stated on any installation documents supplied with the unit. This is basically the number of steps that each motor needs to take to move the cutting head 1mm

    The limitation of the software is that it will only process 1000 lines of GCODE data. GCODE being the standard language for CNC machines and is generated by all sorts of design packages.

    The 1000 line limitation is something which is likely to be an issue for most users fairly soon after they start to try to mill anything other than some demo files e.g. the outline of the “Roadrunner” cartoon character, and the best option for most people is to buy the full / official version of Mach3, which at the time of writing, retails for $175 (USD).

    There are other options, including using Linux to control the mill, and also to buy a dedicated USB to CNC adaptor – which replaces parts of the electronics in the control box; however I have not investigated these options as yet.

    Once you have connected it all up, and calibrated the software, you should be able to move all 3 axis motors and do a test mill of the “Roadrunner” icon to confirm that everything is working OK.

    Tip:  One thing I do to test a new set of GCODE is to set the Z  zero position of the unit to about 5cm above the actual milling bed, and without a cutter in the chuck, then run the GCODE without the spindle / cutter motor running.

    Finally after quite some time you are getting slightly closer to being able to mill your own PCBs.¬†¬† Generating the GCODE for the PCB is relatively simple. An open source package called PCB-GCODE (http://www.pcbgcode.org/ ) can convert either Gerber files to GCODE, or there is a User Language Program (ULP) for Cadsoft Eagle which will generate the GCODE “tap” files from within Eagle.

    With the “etch” file loaded into Mach3, you can attempt to mill your first PCB, but first there are a few more hurdles to overcome ūüėČ

    Securing the PCB to the milling bed

    The main problem with milling a PCB is how to secure the PCB down onto the milling bed. As you will be drilling holes through the PCB as well as milling away the copper, you will need to mount something like a small sheet of wood onto the milling machine, and mount the PCB onto the wood. The best thing I’ve found so far to mount the PCB onto is MDF. The MDF needs to be thick enough so that the drill can completely penetrate the PCB and not drill into the aluminum bed of the mill. If you are careful, you can probably use 3mm or 5mm MDF, however these are likely to be too weak to attach to the bed using the bolts supplied with the machine, so I normally use 10mm or even 12mm MDF, as this feels really secure and robust. MDF has good dimensional stability as long as it doesn’t get wet or absorb a lot of moisture, but should work in most indoor environments unless you live somewhere very humid.

    Initially I used masking tape to hold the PCB onto the MDF, however this doesn’t work particularly well, as the edges of the PCB soon start to lift off slightly, as most PCB I have appears to be not entirely flat.

    If the PCB is not absolutely flat you will have major issues with the milling process. This is because the normal cutting head for milling PCB’s is a 20 deg or 30 deg V shaped engraving tool, hence the width of the section that is milled is dependent upon the depth that the point of the cutter is below the surface. So if your PCB lifts off by, for example 0.5mm, this is going to cause the cutter to penetrate into the board by an additional 0.5mm, which will mean it cuts a path which is approximately 0.25mm wider than you expect (assuming you are using 30 deg V cutter), this can be the difference between a track existing or getting milled away.

    CNC with secured PCB
    CNC with secured PCB

    The way I hold the PCB in place is to clamp down at least 3 sides of the board using steel plates. I bought some steel fixing plates from a DIY store, which are about 15cm long by 3cm wide and about 4mm thick. I’m not entirely sure what use they have in building construction, but if you overlap them onto the edge of the PCB by a 5mm (or a bit less) them screw them down onto the MDF, the PCB is prevented from lifting on any of the sides. Of course if you have a PCB which bows up in the middle you will still have a problem, so you should try to use PCBs that are as flat as possible, and even possibly flatten them before hand by storing them flat under pressure e.g. between some heavy books.

    I’ve seen some examples on the web, where people just used a small clamp in the middle of each side, and I think this would be equally effective; but either way its very important to clamp the PCB onto the MDF as flat as possible.

    Cutting tool height adjustment

    The next important thing is to set the exact height of the cutting tool. For a while I’d been using a sheet of paper as a feeler guage, and lowered the cutting head a little at a time, until it was in contact with a sheet of paper placed on top of the PCB, so that I could feel definite resistance, when trying to move the PCB, however this isn’t really accurate enough.

    A better approach is to use the a continuity meter (buzzer / beeper) setting in a normal multimeter to determine when there is an electrical connection between the cutting head and the PCB. To do this I attach crocodile chips to the PCB clamps and to the cutting bit, and slowly jog the cutting head height down 0.01mm at a time until my meter beeps, I then raise the cutter a few 1/100 of a mm until it stops beeping, and I know its very very close to zero.

    Even with the PCB clamped down, there can also be minor differences in its height, so its best to do this Z height calibration in the middle of the area you are about to mill. There is actually a program which will scan the PCB using this electrical connection and re-map the Z height of the milling to take account of minor fluctuations in the PCB thickness / height, however to use it you need to modify the control unit to accept the continuity as the Z zero limit, and so far in practice I have not found it necessary to go to this level of complexity.

    Milling

    When you have finally calibrated everything, you can start to mill the board, and hopefully you will not have too many problem with board thickness or warp.

    After the “etch” path has been milled, you need to change your cutting bit to a 1mm or 0.9mm PCB drill, and load the “drill” tap GCODE file. Its important to not loose the X and Y calibration when you are changing the cutting bit for the drill bit, otherwise it will be very hard to get the machine re-positioned correctly to drill the holes in the correct locations.

    I have attempted to use the same continuity technique to calibrate the Z zero on the drill, but I think perhaps the drills come pre-coated with some varnish, as they are not good conductors when they are new.

    Its also very easy to snap the PCB drill, by applying downward pressure. So under no circumstances “jog” the drill down onto the PCB surface when its not spinning, otherwise you stand a very high chance of snapping it. Trust me, I have snapped one drill this way, and snapped a second drill trying to manually drill out some holes which the mill didn’t drill completely through a board.

    As the depth of the drill holes isn’t that critical, as long as its completely through the PCB, its safer to use the paper technique, with some thicker paper, to get the Z height about right, even if its 0.5 or 1mm above the board, and set the drilling depth to 2,3 or even 4mm to ensure the drill goes completely though the PCB. (Assuming you have a decent thickness of MDF below the PCB).

    After the board has been drilled, then and only then, should you release the clamps are remove the board.

    Results so far…

    So far I have only milled single sided boards. Milling double sided boards is technically possible, however I can see a number of possible problems around the re-registration of the zero point (X,Y), as after the board is flipped over, it would need to be repositioned to within about 0.05 of a mm in both X and Y of its original position. This can probably be achieved by adding a calibration drill hole at 0,0 in the board GCODE file. However the other problem is rotation. i.e 2 calibration holes would be needed to ensure the board is not slightly rotated. Or perhaps some sort of metal jig could be bolted to the MDF prior to milling the first side, to ensure that the board is refitted in exactly the same location.

    I’m personally very skeptical about the feasibility of doing this. I know it can be done, but I think it would take quite a lot of practice and experimentation to develop a process to make reliable double sided PCB’s a practicality.

    However overall, production of single sided prototype boards is entirely possible on the CNC 3020, it just takes some time and effort.

    10 Comments "

    Arduino STM32 – USB Serial and DFU

    June 18th, 2015

    I often get asked about why the USB Serial doesn’t seem to work on Maple mini or generic STM32F103 boards loaded with the STMduino-bootloader.

    If you buy a brand new Maple mini, and plug it into your PC or Mac or Linux box. Do not be suprised if you only see a DFU device. This is normal.

    Just compile and upload a blank sketch.¬† Even a blank sketch will contain the Serial USB code, and your board should then appear as a “Maple Serial” device.

    There is a common missconception that the STM32duino-bootloader, and the older Maple bootloader, contain both DFU (upload) USB support and also “Maple Serial” (USB Serial) functionality. However this is not the case.

    Originally when Leaflabs wrote the Maple bootloader (back in around 2012) they tried to include both  DFU and Serial functionality, however they found issues with this under Windows. This is because the DFU and Serial functionality requires the use of 2 completely different (built in) drivers in Windows; when the Maple board is only one USB device.

    Normally manufacturers create composite USB devices in this case, i.e one USB driver that performs both the DFU and Serial functions. But creation and certification of custom drivers for Windows is non-trivial and expensive. Hence LeafLabs chose to separate the DFU and Serial USB functionality, so that only the DFU driver is used when the bootloader is running and only the Serial driver is used when the Arduino sketch is running.

    This method allows the use of 2 separate Windows drivers – both of which come as standard on all Windows installations.

    Although the functionality of both DFU and USB Serial could have been included in the bootloader, it would make the bootloader and sketch core code (libmaple) more complicated, as the sketch would need to communicate with the bootloader in order to send and receive serial data.

    So Leaflabs chose to go with the simpler option of the bootloader only containing the DFU functionality, and for the USB Serial to be compiled as part of the sketch. Although this is the simpler option, its probably the best one, because if the Serial USB support was contained in the bootloader, the amount of additional code to allow the sketch to send and receive Serial via the bootloader would make the overall size of the bootloader and sketch slightly larger.

    Sketches do take slightly longer to upload than if they did not contain the USB Serial functionality, but uploads via DFU are generally faster than AVR Arduinos, so this isn’t a serious concern.

    Another consequence of splitting the functionality, is that if the sketch crashes, then the USB Serial will also crash, and often the USB Serial device will not appear at all.

    And… any board that has been freshly installed with a bootloader, will only appear as a DFU device, because the bootloader checks to see if a valid sketch is in the program (flash) memory, and if not the bootloader continues to stay in DFU mode until a valid sketch has been upload.

     

     

    2 Comments "

    Particle (aka Spark) Photon, first impressions

    June 3rd, 2015

    I finally received the 2 Spark aka Particle, Photon boards today.

    I ordered 2 of these way back at the end of last year when one of my clients was interested in doing some environmental monitoring using wifi and an IoT device.

    Initially delivery time was March, but they finally arrived now (June).

    I’m not sure if I should have expected more, but they arrived in a plain white padded bag, albeit in custom made matchboxes, but with no other paperwork than the shipping note.

    But I’m used to receiving all sorts of devices from AliExpress and eBay in similar packaging (less the matchboxes)

    So. What do to next. Googling “Particle Photon” just takes me to their store.

    After searching a bit more I find their landing page site, but that seems to take me back to the store.

    But eventually I found some instructions http://docs.particle.io/photon/

    So… It seems to say I need an App for my phone. So I try to install it on my iPhone… But, oh no, it needs the iOS 8, and my old phone is known not to work well with iOS 8, so I’m still on iOS 7.

    So…. That’s a fail then.

    Ok. How about going to their site and not using an App.

    Well, you are greeted by a site that just has a login / register box. No information, wiki no forum. You must create an account.

    At this point, I’m afraid they lost me, I don’t register for stuff unless I know what I’m getting and why. I normally expect to be able to read stuff and perhaps have some basic features without needing to sign my rights away. After all, if JSFiddle can manage it….

     

    So were does this leave things.

    Well, after pressing the two buttons in various orders, and looking at the windows device manager, I can see that it initially appears as a Spark Photon, and loading the drivers this gives a usb serial device

    But more interestingly, if you hold down the other button and press reset, the board enumerates on USB as a DFU device.

    The problem is that windows won’t use this DFU device, unless you load a driver (well, you need to associate the USB VID/PID with the built in Windows DFU driver. It doesnt look like Spark aka photon have a signed driver for this (well I can’t find one). There are some work arounds on Github e.g.https://github.com/hpssjellis/dfu-util-windows-spark-core-photon

    But I that repo has not been touched for 5 months and didn’t look complete

     

    To be honest, I know how to create a driver association, as I can use the same system that we used on Arduino_STM32, but it would be good, if I didn’t have to rebuild a special version of WMI to install the DFU driver for the Photon, after all its a commercial product.

     

    I feel I’ve wasted an hour on this and got nowhere, and my time would be better spent on the ESP8266, as even though its less polished, it does work ! and is a fraction of the price.

    2 Comments "

    Improved Maple bootloader for STM32

    April 26th, 2015

    The LeafLabs Maple bootloader has a number of shortcommings which I have addressed by making a new version which dovetails with new features in Arduino STM32 Read the rest of this entry “

    5 Comments "

    HM10 iBeacon: Disappointing battery life

    April 15th, 2015

    Conducting some accelerated batter life test on a HM10 BLE module as an iBeacon, revealed some disappointment battery life results.

    Read the rest of this entry “

    11 Comments "

    Work around for Arduino STM32 with IDE V 1.6.3 or newer

    April 13th, 2015

    Changes were made to the Arduino IDE in version 1.6.2 which prevent the STM32 files from compiling. This article describes a work around that solves this problem.

    Read the rest of this entry “

    1 Comment "

    Bug fixing the eWay plugin for OpenCart

    April 10th, 2015

    Last week, one my my clients changed their online payments processor to eWay, but the eWay plugin did not seem to work on the custom version of OpenCart which we had created from them.

    Read the rest of this entry “

    No Comments "

    Low cost BLE programmer fail

    April 9th, 2015

    In my quest to find a low cost programmer for the CC2540 and CC2541 series of Bluetooth Low Energy Soc devices, commonly used as BLE beacons, I bought a device sold as a “Zigbee debugger emulator” from eBay.
    Read the rest of this entry “

    8 Comments "

    ESP8266 for Arduino – Discontinued

    April 7th, 2015

    As a follow up to my posting about ESP8266 for Arduino. As expected, things are moving very fast in this arena, and my GitHub repo has now been superseded.
    Read the rest of this entry “

    No Comments "

    Waking HM10 and HM11 BLE boards

    April 5th, 2015

    Just a quick note on how to resolve serial connectivity issues with Bluetooth Low Energy boards (BLE) sold as iBeacons or iBeacon Sensors.
    Read the rest of this entry “

    3 Comments "

    ESP8266 for Arduino

    March 29th, 2015

    I suspect this will be a short lived project, because the original project team will hopefully refactor their repo ,(http://github.com/esp8266/arduino) to address the need to download a custom version of the whole of the Arduino IDE.
    Read the rest of this entry “

    No Comments "

    Easy Bluetooth Low Energy connector

    March 26th, 2015

    Recently, I’ve been testing some HM10 and HM11 Bluetooth Low Energy modules for a BLE beacon project.

    But the problem with these BLE modules is that they come as a bare board, hardly bigger than a postage stamp, which is great for deployment but terrible for testing, as they have 1.5mm spaced connectors on the side, rather than the traditional 1/10 inch.

    Anyway, I thought I’d share my simple solution to connecting them to a $5 USB to serial adaptor.

    All you need is a single in line socket, which are readily available from multiple suppliers on eBay etc, as they are used when making Arduino shields.

    The trick is to use a socket with the same number of pins as the USB 2 serial adaptor, so its hard to plug it in the wrong way around.

    Firstly, you need to glue the socket to the back of the HM10 module. I use a hot glue gun, but any reasonably strong glue will do.
    Then its just a question of cutting the pins on the inline socket to the appropriate length, (around 2 or 3 mm long is idea), and use some fine gauge wire (I use wirestrip wire), so connect the 4 necessary connections, GND, 3.3V, TX and RX from the inline socket to the pins on the HM10

    You can then simply plug the module into your USB to serial adaptor when you need to program it via the PC

    The chances of plugging the HM10 around the wrong way, are quite low, as the are 6 pins on the usb to serial adaptor and the socket is 6 pins, so all you need to remember is to put the HM10 chip side up like the USB to serial adaptor.

    2 Comments "