Thursday, December 28, 2017

Converged IoT Developer Platform

I installed a popular utility and a popular racing drone motor on a helicopter for IOT/MQTT/COAP research to see what would happen. It flipped, proximity-dived, and then cruised for 35 minutes straight, beating the next best commercial platform of 250 grams by 50+% extra endurance! The fuselage is a Blade Fusion 180 body; the main motor size is 2806 of utility inspector drones. The flight computer is taken from a real estate video shooting drone HGHGLRC Sector25cr (250 grams). The tail motor is from the racing quadcopter HGLRC Petrel 120x.  Is it nice if highways are patrolled by camera drones to broadcast the video of traffic accidents, and an AI server phones motorists to get out of the road at the immediate exit before lining up in a traffic jam?

The build and procedure notes are

The part listing is in the following table. Combo products are entries across different spreadsheets of this project, but split combo pricing to individual entries. Shipping discounts for multiple items from a vendor have been applied. No volume discounts.
The Horizon (Blade brand) components are priced the same on eBay and Amazon both with free shipping, as shown in the eBay and Amazon checkouts.
The entire craft is built without a machine shop and can be repaired by professionals in a car.  Only light hand tools and light electric tools powered by car batteries are needed. This creates jobs.

The World Is The Supply Chain Even For Specialty Parts - Cusped Airfoil

Cusped airfoil 10.5% thickness (joukowsky10.5 for short) rotor blades are interchangeable with conventional parts: The production build's cusped airfoil on the rotor blades is known to extend the efficient angle of attack range for thin blades, discussed in https://estebanhufstedler.com/2020/09/24/joukowski-airfoil-l-d/ and https://estebanhufstedler.com/2020/07/14/improving-the-naca-00xx-airfoil/.  The Fusion 180mm blade is modified from the NACA0010.5 thin airfoil with a cusped trailing edge. The result is that its fuel economy is nearly identical to that of the NACA0012 medium-thickness airfoil under the same operating parameters (blade speed and alpha). The reduced drag for the high angle of attack also keeps the stall angle of attack outside the operating angle of 10 degrees, similar to NACA0012. One video of the endurance test (6 degrees collective pitch), 3 videos of performance tests (8 degrees), and 2 videos of an extraneous test (10 degrees) are below in order. The NACA0012 blades operate with optimal efficiency at 5 degrees of alpha in static tests, and due to the quirk of vertical rotor fluid dynamics, the optimal angle of attack for cruising is 1 degree higher than that of the static test. Since the cusped blades perform nearly identically to NACA0012 blades, the endurance cruising test was done with 5+1=6 degrees of collective pitch.




The World Is The Prototype Lab

The Align 300x has the same diameter and nominal length as those in the Blade Fusion 180. Align uses metric length 38 mm; Blade uses imperial length 1.5 inches. However, all suppliers use metric bolt threads and rod diameters.

Newcomer brands, not in parts list, Skystars and SParkhobby are just as good, if not better: Four hardware bugs of the HGLRC Zeus flight computer prevent it from setting up ESCs without re-soldering. 
1) Betaflight Software version 4.2.5 with the Zeus does not allow a reboot sequence to enter boot loader mode.
2) Not allowing entering boot loader mode means the hardware boot loader button needs to be used.
3) Using the hardware boot loader button means UART1 connecting to RF control receiver blocks USB flashing betaflight software version 4.5.2 unless UART1 is desoldered.
4) LED signal wire reassigned as S5 signal wire cannot flash FVT ESC, which needs resoldering to S4 pin to do the flashing.
Skystar Mini F4 solves all 5 hardware bugs. 
The flight software is here hex .
The dump all configuration is here dump_all  .

The only difference between Skystars F7 and HGLRC F7's config is the pinout assignments and physical chip orientations.
$ diff dump_all_converged_IoT_HGLRCF722_6pin.txt dump_all_converged_
IoT_SKYSTARS_MINIF7.txt
6,7c6,7
< # Betaflight / STM32F7X2 (S7X2) 4.5.2 Mar 28 2025 / 21:47:17 (024f8e13d) MSP API: 1.46
< # config rev: 48588b7
---
> # Betaflight / STM32F7X2 (S7X2) 4.5.2 Aug  6 2025 / 03:55:33 (024f8e13d) MSP API: 1.46
> # config rev: 21f88d7
240,241c223,224
< serial 0 2 115200 115200 0 115200
< serial 1 64 115200 57600 0 115200
---
> serial 0 64 115200 57600 0 115200
> serial 1 0 115200 57600 0 115200
243,244c226,228
 
A summary of the dimensions of all component options is in the following table. And the reference component diagram is beneath the table. 

The interchangeable Blade 180cfx rotor (1.69g hub + 2.24g grips +0.82g thrust +0.90g radial + 0.53g blades bolt +  0.25g dfc = 6.43g) weighs 0.45 gram less than production build (1.4g hub + 3.7g grips + 0.1g washers + 0.9g dfc +0.8g dfc bolt = 6.9g). The grips are nearly identical (4.48 grams) in weight to production build when blade and DFC boltings are included; the DFC links are 0.4 grams lighter when the radial swasharms are included as part of DFC links.

This interchangeable Blade 180cfx rotor has thrust bearings and has zero slop of the feathering shaft, as is, without flanged washers. When you look up the rotor dimensions chart, you see a 0.25 mm hub-grip gap, but this gap is filled by the rubber grommet fully. 

The installation is more complex with thrust bearings than the production build without thrust bearings. Production can not use the thrust bearings unless an assembly line is trained for it. The Blade Fusion 180 rotor has been verified in the substitution note, but Blade 180cfx rotor has not been verified.























Sunday, July 16, 2017

C Programming Raspberry Pi MQTT Drone PWM



Drones commonly require real time programming because a split second control delay of a tail rotor can mean 180 degrees difference of a helicopter's heading.  For this reason, flight controller programming is often done with C language on a micro controller, where control logic can be optimized on a per-CPU-instruction basis.

However, a new trend has emerged to use Raspberry Pi Zero as a robotic controller to take advantage of the ubiquitous Linux programming, which the OS hides the underlying custom circuitry of micro controllers and presents the abstract programming interface to the programmers so that a program can be portable between different hardware systems. Adafruit has many tutorials focus on the Python library for the I2C devices. But, again, few resources provide the comprehensive view of the requirement of real time C programming. So, as soon as I found a hint of a C library controlling I2C servos, I have to jump in and test drive its performance.

The solution is https://github.com/Reinbert/pca9685 . Steps I took:
  1. "Burn" SD Card with 2017-06-21-raspbian-jessie-lite.img , which is public downloadable from raspberrypi official site. After first powering on with the "burned" SD, wait for the disk expansion to finish in a few minutes while green LED light busy flashes.
  2. Wire up as the following diagram, 
  3. The usual IP connectivity chores. First thing is to get UART access through USB-FTDI adapter. Raspberry Pi Kernel side needs "enable_uart=1" in /boot/config.txt . To do so, insert the SD in to my PC to mount it .  
  4.  Then try to get IP access. Comment out the wlan entries in /etc/network/interfaces , and replaces it with my AP access credential,
    auto wlan0
    iface wlan0 inet static
    address 192.168.43.5
    netmask 255.255.255.0
    gateway 192.168.43.1
    wpa-ssid "pc36000"
    wpa-psk "A...."
    Then, systemctl enable ssh , and reboot. Once IP SSH access is successful, apt install vim , and comment out the "enable_uart=1" .
  5. apt-get install git-core
    git clone git://git.drogon.net/wiringPi
    cd wiringPi/
    ./build
  6. git clone https://github.com/Reinbert/pca9685.git
    cd pca9685/src/
    sudo make install
  7. cd; mkdir mqtt-pizero
    cd mqtt-pizero
  8. vim servo-check.c ; The content follows,
    #include <pca9685.h>
    #include <stdio.h>

    int calcTicks(float impulseMs, int hertz)
    {
    float cycleMs = 1000.0f / hertz;
    return (int)(4096 * impulseMs / cycleMs + 0.5f);
    }

    int main()
    {
    int fd = pca9685Setup(300, 0x40, 50);
    pca9685PWMReset(fd);

    float millis = 1.5;
    int tick = calcTicks(millis, 50);
    pwmWrite(300, tick);

    while (1)
    {
    delay(1000);
    millis = 1.8;
    tick = calcTicks(millis, 50);
    pwmWrite(300, tick);

    delay(1000);
    millis = 1.2;
    tick = calcTicks(millis, 50);
    pwmWrite(300, tick);
    }
    }
  9. gcc servo-check.c -o servo-check -l wiringPiPca9685 -l wiringPi
  10. apt install i2c-tools
  11. sudo vim /boot/config.txt ;  uncomment the following line,
    dtparam=i2c_arm=on
  12. sudo vim /etc/modules; content follows,
    i2c-dev
    i2c-bcm2708
  13. sudo vim /etc/modules-load.d/modules.conf; content follows,
    i2c-dev
    i2c-bcm2708
  14. sudo sync ; sudo reboot
  15. Once rebooted, check i2c device is at 0x40 by gpio readall ; then cd mqtt-pizero/ ; ./servo-check

Friday, May 19, 2017

Inbound And Outbound Dialings Are "Institutional"


Why are there inbound and outbound boundaries with phones but not with Facebook/Google/Apple voice chats? Can we answer that question by looking at the smallest bits and pieces ourselves? I think so. But, what is the implication behind all these?

OK. In my diagram above, when lines, connections touch, it means they are associated. The purple inbound dialings do not touch any trunk lines, which means the inbound dialings are not associated with any particular trunk line. The orange PBX outbound dialing does not touch any phone line and is not associated with any phone protocol. The PBX outbound dialing, however, does touch SIP trunk line, which means it only goes out on the SIP trunk and not H323 protocol. So, all that means is that an inbound dialing does not care what the outbound trunk or protocol will be; an outbound dialing does not care what the inbound phone or protocol is. This is the essence of the PSTN call leg and the essence of VOIP.
For the green VOIP signal dash lines, the corresponding configs are in pjsip.aor.conf ,
[101]
type=aor

[102]

type=aor
[SIP-to-CUCM]
type=aor
contact=sip:10.1.10.76:5060


, and in ooh323.conf ,
[10.1.10.76]
type=friend
context=from-trunk
host=10.1.10.76
port=1720
[ekiga223]
IP=10.1.10.223
port = 1720
type=peer
context=from-external
. The purple inbound dialings are in extensions_additional.conf ,
[ext-did-0002]
exten => 18001231101,1,Set(__DIRECTION=INBOUND)
exten => 18001231101,n(dest-ext),Goto(from-did-direct,101,1)

exten => 18001231102,1,Set(__DIRECTION=INBOUND)
exten => 18001231102,n(dest-ext),Goto(from-did-direct,102,1)

exten => 18004561203,1,Set(__DIRECTION=INBOUND)
exten => 18004561203,n(dest-ext),Goto(from-did-direct,203,1)
, and outbound dialings are also in extensions_additional.conf
[outrt-1] ; siptrunk
exten => _1800321XXXX,1,Macro(user-callerid,LIMIT,EXTERNAL,)
exten => _1800321XXXX,n,Macro(dialout-trunk,2,${EXTEN:7},,off)

[outrt-2] ; h323trunk
exten => _1800654XXXX,1,Macro(user-callerid,LIMIT,EXTERNAL,)
exten => _1800654XXXX,n,Macro(dialout-trunk,1,${EXTEN:7},,off)

. The FreePBX GUI generates the entire extensions_additional.conf and pjsip_aor.conf . ooh323.conf is entirely manually created. All configurations are downloadable here, https://drive.google.com/file/d/0B2NfHoyfFf1aTWR6QUxQQVhkQWc .
The GUI dialogs are







The voice-vlan enabled router configuration is as  https://drive.google.com/file/d/0B2NfHoyfFf1aNXRhMnJyU01Zb0E .
The CUCM GUI screenshots are 


So, a call leg becomes a proxy in the TCP/IP/HTTP world so that the destination and source phones do not know the IP address of each other. The very definition of protocol proxy. It provides some isolation("does not care") of parts of the network while requiring the border routers to have the insights into the protocol. Speaking of proxy, do you know that this very page you are viewing is a proxy'ed page when you are at blog.mpls-phone.com, which is 34.225.89.249 . The true IP address of the web server is google's blogger web server IP address. That will be yet another posting about the Apache configuration that made the proxy.


Sunday, May 7, 2017

Watching The Branch Office Traffic


The branch office is on the far side of the WAN, and predictably the SCCP phones are on the branch router's EtherSwitch ports. So, how to find the actual voice packets that we want to know how much network bandwidth is utilized?

  1. Easy, just browse the flow exports pcap. But the number of voice flows is actually a very small fraction of the number of signaling flows. Just look at this screenshot of pcap search, 
    , the first actual voice flow is at packet 280. The IP source/destination is indistinguishable between small, frequent signaling flows and actual voice flow. It turns out, among the thousands of packets, only 3 are actual voice traffic flow exports. Browsing is out of the question. The real C1900's flow pcap is at https://drive.google.com/file/d/0B2NfHoyfFf1aMzlNbnM0SkhpQTg/view?usp=sharing . You can try it yourself. 
  2. Easy, just search the TOS on the flow exports pcap, right? The problem is that the hardware phone is subject to change without notice, so the TOS number is unknow. 
  3. Why not search for flow packet size? The size is actually unknown as well. In above screenshot, there is a roughly 36MB sized packet every half an hour of 1800 seconds. The string "Octets: 360" seems very unique. However,  how do you get this number? Intranet voice runs at the common 64kbps for u/alaw 8kps sample,  8 bits quantization. (64+16overhead)kbps * 1800 seconds / 8bit/Byte . It should be 18MB. It turns out, the counting is done twice for each packet while ingress to the router and at the egress interface. There is no certain way to foresee the search string "Octets: 360".
It turns out, ELK search is necessary to figure out what search strings we want! And that search is performed by ranking all flow size(bytes), and the 36MB stands out in the crowd of 1KB short signaling flows.

The ELK graphing is as below picture after taking out all signaling flows,
. Notice, that straight ELK can't handle niche fields like VLAN ID. When VLAN ID is present, ELK may simply discard the whole flow. That is why we need to alter the flow content in an editor in the terminal.

Now, after going through so much, are we sure that modern phone voice indeed is with 8kps sampling rate? According to Math, 8 kHz sampling rate can only transmit 4kHz sound, and that seems too low for high human hearing. The answer is that modern SD phone speech is defined as from 300 to 3400 Hz. We can hear a lot wider range of sounds than we can make. And the speech encoding is not meant to transmit Hi-Fi music, waves, etc.

Saturday, May 6, 2017

Mind In The Data Center Zone


Zoning out on a compact setup that has everything.


The MQTT logs come from the Internet, sourced from a ARM mosquitto program. And the Kibana display of the MQTT traffic flow is this,

, notice TOS is marked down to precedence 1 (TOS 32 decimal), by T-Mobile. And a hundred of these IoT sensors looks like the picture at the top.