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

No comments:

Post a Comment