2-channels NODii-SERVO controller

by Johnny

 

FEATURES

The 2-channels NODii-SERVO controller raises the performance bar for serial servo controllers with features such as a native UART and I2C interface and internal scripting control.
Whether you want high-performance servo control (0.25µs resolution with built-in speed and acceleration control) or a general I/O controller (e.g. to interface with a sensor or ESC via your UART and I2C interface), this tiny, versatile device will deliver.

Main Features
Three control methods: I2C, TTL (5V) serial, and internal scripting 0.25µs output pulse width resolution (corresponds to approximately 0.025° for a typical servo, which is beyond what the servo could resolve)
Pulse rate configurable from 33 to 100 Hz (2)
Wide pulse range of 64 to 3280 µs (2)
Individual speed and acceleration control for each channel
Channels can be optionally configured to go to a specified position or turn off on startup or error
A simple scripting language lets you program the controller to perform complex actions even after its I2C and serial connections are removed
Voltage BAT: 6-12V
Voltage for servo: 6-12V

 

SCHEMATIC

 

LAYOUT

One thought on “2-channels NODii-SERVO controller

  1. We can use source code below for test this board:

    /*
    * File: servo_controller.c
    * Author: NGUYEN
    *
    * Created on October 31, 2016, 7:14 PM
    */
    // PIC18F14K50 Configuration Bit Settings

    // ‘C’ source line config statements

    #include
    #include
    #define _XTAL_FREQ 12000000
    //#include “pwm.h”
    #include

    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.

    // CONFIG1L
    #pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection bits (No CPU System Clock divide)
    #pragma config USBDIV = OFF // USB Clock Selection bit (USB clock comes directly from the OSC1/OSC2 oscillator block; no divide)

    // CONFIG1H
    #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
    #pragma config PLLEN = OFF // 4 X PLL Enable bit (PLL is under software control)
    #pragma config PCLKEN = ON // Primary Clock Enable bit (Primary clock enabled)
    #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor disabled)
    #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

    // CONFIG2L
    #pragma config PWRTEN = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
    #pragma config BORV = 19 // Brown-out Reset Voltage bits (VBOR set to 1.9 V nominal)

    // CONFIG2H
    #pragma config WDTEN = OFF // Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
    #pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)

    // CONFIG3H
    #pragma config HFOFST = ON // HFINTOSC Fast Start-up bit (HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.)
    #pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RA3 input pin disabled)

    // CONFIG4L
    #pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
    #pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
    #pragma config BBSIZ = OFF // Boot Block Size Select bit (1kW boot block size)
    #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

    // CONFIG5L
    #pragma config CP0 = OFF // Code Protection bit (Block 0 not code-protected)
    #pragma config CP1 = OFF // Code Protection bit (Block 1 not code-protected)

    // CONFIG5H
    #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block not code-protected)
    #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

    // CONFIG6L
    #pragma config WRT0 = OFF // Table Write Protection bit (Block 0 not write-protected)
    #pragma config WRT1 = OFF // Table Write Protection bit (Block 1 not write-protected)

    // CONFIG6H
    #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers not write-protected)
    #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block not write-protected)
    #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

    // CONFIG7L
    #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 not protected from table reads executed in other blocks)
    #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 not protected from table reads executed in other blocks)

    // CONFIG7H
    #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block not protected from table reads executed in other blocks)

    unsigned int duty1 = 0;

    void SetPWM1(unsigned char pwm_width1){
    unsigned char pwm_lsb1;
    pwm_width1*=10; // change value from 0-25 to 0-250
    //10 Bits – 2 LSB’s go in CCP1CON 5:4, 8 MSB’s go in CCPR1L
    pwm_lsb1 = pwm_width1 & 0b00000011; // Save 2 LSB
    CCPR1L = pwm_width1 >> 2; // Remove 2 LSB and store 8 MSB in CCPR1L (only 6 bits as max duty value = 250)
    pwm_lsb1 = pwm_lsb1 <> 2; // Remove 2 LSB and store 8 MSB in CCPR1L (only 6 bits as max duty value = 250)
    pwm_lsb2 = pwm_lsb2 << 4; // Move 2 LSB into correct position
    //CCP1CON = pwm_lsb1 + 0b00001100; // duty lowest bits (5:4) + PWM mode
    }

    void main(void) {
    T0CON = 0b11000111; // 8 bit timer, prescaler 1:256, TMR0 on
    TMR0L = 178; // 200Hz
    INTCON2bits.TMR0IP = 0; // interrupt priority 0
    INTCONbits.TMR0IE = 1; // timer0 interrupt enabled

    // Clear the peripheral interrupt flags
    PIR1 = 0;

    ANSEL=0; // Digital
    ANSELH=0; // Digital
    ADCON0=0; // A2D Off
    CM1CON0=0; // Comparators off
    CM2CON0=0; // Comparators off

    //TRISA = 0b00000000; // Set Ports
    //TRISB = 0b00000000; //
    TRISC = 0b00011000;

    /*
    * PWM Register Values
    * Oscillator Frequency Fosc = 16000000
    * Clock Frequency Fclk = 4000000
    * PWM Freq = 250 – allows us to use a duty value of 0 to 250
    * Prescaler Value = 16
    * Postscaler Value = 16
    * PR2 = 62
    * Maximum duty value = 250
    */
    T2CON = 0b01111111; // prescaler postscaler to give 250Hz + turn on TMR2;
    PR2 = 62; // gives 250Hz
    CCPR1L = 0b00000000; // set duty MSB – initially 0 – off
    CCP1CON = 0b00001100; // duty lowest bits + PWM mode
    while(1)
    {
    SetPWM1(10);
    }
    }

Leave a Reply