You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • I'm not really agree with you Mike, 10k of members does not mean a better developpement, there will always be only 10 people trying to do something, and 9990 other that will only wait to have something that works without putting there hand in it.
    this is also why I'll only put source code and no hex.

    well, here we go :
    download the UBW source code :

    then open user.c and do the following modifications :

    //after :
    near unsigned char g_RC_timing_ptr;
    //add :
    near unsigned char g_RC_ptr;
    near unsigned char g_RC_next_ptr2;

    //after :
    near unsigned char A_cur_channel;
    //add :
    near unsigned int P_tick_counter;

    //after :
    volatile unsigned int g_RC_value[kRC_DATA_SIZE]; // Stores reload values for TMR0
    //add :
    volatile unsigned int g_RC_Tmp; //300µs-400µs for ppm start

    //after :
    BOOL g_ack_enable;
    //add :
    BOOL g_ppm_enable;

    //after :
    void parse_CU_packet (void); // CU configures UBW (system wide parameters)
    //add :
    void parse_PP_packet (void); // PP Send RC throught PPM

    //in void low_ISR(void) replace :
    if (kWAITING == g_RC_state[g_RC_next_ptr])
    {
    // If the value is zero, then shut this pin off
    // otherwise, prime it for sending a pulse
    if (0 == g_RC_value[g_RC_next_ptr])
    {
    g_RC_state[g_RC_next_ptr] = kOFF;
    }
    else
    {
    // Set the bit high
    if (g_RC_next_ptr < 8)
    {
    bitset (LATA, g_RC_next_ptr & 0x7);
    }
    else if (g_RC_next_ptr < 16)
    {
    bitset (LATB, g_RC_next_ptr & 0x7);
    }
    else
    {
    bitset (LATC, g_RC_next_ptr & 0x7);
    }
    // Set the state to primed so we know to do next
    g_RC_state[g_RC_next_ptr] = kPRIMED;
    // And remember which pin is primed
    g_RC_primed_ptr = g_RC_next_ptr;
    }
    }


    // And always advance the main pointer
    // NOTE: we need to skip RA6, RA7, and RC3, RC4, and RC5
    // (Because UBW doesn't bring those pins out to headers)
    g_RC_next_ptr++;
    if (6 == g_RC_next_ptr)
    {
    g_RC_next_ptr = 8;
    }
    else if (19 == g_RC_next_ptr)
    {
    g_RC_next_ptr = 22;
    }
    else if (kRC_DATA_SIZE == g_RC_next_ptr)
    {
    g_RC_next_ptr = 0;
    }

    if (kPRIMED == g_RC_state[g_RC_primed_ptr])
    {
    // This is easy, throw the value into the timer
    TMR0H = g_RC_value[g_RC_primed_ptr] >> 8;
    TMR0L = g_RC_value[g_RC_primed_ptr] & 0xFF;

    // Then make sure the timer's interrupt enable is set
    INTCONbits.TMR0IE = 1;
    // And be sure to clear the flag too
    INTCONbits.TMR0IF = 0;
    // Turn on Timer0
    T0CONbits.TMR0ON = 1;

    // And set this pin's state to timing
    g_RC_state[g_RC_primed_ptr] = kTIMING;

    // Remember which pin is now timing
    g_RC_timing_ptr = g_RC_primed_ptr;
    }
    //by :
    if(g_ppm_enable)
    {
    if(P_tick_counter==22)
    {
    g_RC_next_ptr2=0;
    if (kWAITING == g_RC_state[g_RC_next_ptr2])
    {
    // If the value is zero, then shut this pin off
    // otherwise, prime it for sending a pulse
    // Set the bit high
    if (g_RC_ptr < 8)
    {
    bitclr (LATA, g_RC_ptr & 0x7);
    }
    else if (g_RC_ptr < 16)
    {
    bitclr (LATB, g_RC_ptr & 0x7);
    }
    else
    {
    bitclr (LATC, g_RC_ptr & 0x7);
    }
    // Set the state to primed so we know to do next
    g_RC_state[g_RC_next_ptr2] = kPRIMED;
    // And remember which pin is primed
    //g_RC_primed_ptr = g_RC_next_ptr2;
    }
    // And always advance the main pointer
    // NOTE: we need to skip RA6, RA7, and RC3, RC4, and RC5
    // (Because UBW doesn't bring those pins out to headers)
    //g_RC_next_ptr2++;
    /*if (9 == g_RC_next_ptr2)
    {
    g_RC_next_ptr2 = 0;
    }*/

    //if (kPRIMED == g_RC_state[g_RC_primed_ptr])
    //{
    // This is easy, throw the value into the timer
    TMR0H = g_RC_Tmp >> 8;
    TMR0L = g_RC_Tmp & 0xFF;

    // Then make sure the timer's interrupt enable is set
    INTCONbits.TMR0IE = 1;
    // And be sure to clear the flag too
    INTCONbits.TMR0IF = 0;
    // Turn on Timer0
    T0CONbits.TMR0ON = 1;

    // And set this pin's state to timing
    //g_RC_state[g_RC_primed_ptr] = kTIMING;

    // Remember which pin is now timing
    //g_RC_timing_ptr = g_RC_primed_ptr;
    //}
    P_tick_counter=0;
    }
    else
    {
    P_tick_counter++;
    }

    }
    else
    {
    if (kWAITING == g_RC_state[g_RC_next_ptr])
    {
    // If the value is zero, then shut this pin off
    // otherwise, prime it for sending a pulse
    if (0 == g_RC_value[g_RC_next_ptr])
    {
    g_RC_state[g_RC_next_ptr] = kOFF;
    }
    else
    {
    // Set the bit high
    if (g_RC_next_ptr < 8)
    {
    bitset (LATA, g_RC_next_ptr & 0x7);
    }
    else if (g_RC_next_ptr < 16)
    {
    bitset (LATB, g_RC_next_ptr & 0x7);
    }
    else
    {
    bitset (LATC, g_RC_next_ptr & 0x7);
    }
    // Set the state to primed so we know to do next
    g_RC_state[g_RC_next_ptr] = kPRIMED;
    // And remember which pin is primed
    g_RC_primed_ptr = g_RC_next_ptr;
    }
    }


    // And always advance the main pointer
    // NOTE: we need to skip RA6, RA7, and RC3, RC4, and RC5
    // (Because UBW doesn't bring those pins out to headers)
    g_RC_next_ptr++;
    if (6 == g_RC_next_ptr)
    {
    g_RC_next_ptr = 8;
    }
    else if (19 == g_RC_next_ptr)
    {
    g_RC_next_ptr = 22;
    }
    else if (kRC_DATA_SIZE == g_RC_next_ptr)
    {
    g_RC_next_ptr = 0;
    }

    if (kPRIMED == g_RC_state[g_RC_primed_ptr])
    {
    // This is easy, throw the value into the timer
    TMR0H = g_RC_value[g_RC_primed_ptr] >> 8;
    TMR0L = g_RC_value[g_RC_primed_ptr] & 0xFF;

    // Then make sure the timer's interrupt enable is set
    INTCONbits.TMR0IE = 1;
    // And be sure to clear the flag too
    INTCONbits.TMR0IF = 0;
    // Turn on Timer0
    T0CONbits.TMR0ON = 1;

    // And set this pin's state to timing
    g_RC_state[g_RC_primed_ptr] = kTIMING;

    // Remember which pin is now timing
    g_RC_timing_ptr = g_RC_primed_ptr;
    }
    }

    //and replace :
    if (INTCONbits.TMR0IF)
    {
    // Turn off Timer0
    T0CONbits.TMR0ON = 0;

    // Clear the interrupt
    INTCONbits.TMR0IF = 0;

    // And disable it
    INTCONbits.TMR0IE = 0;
    if (kTIMING == g_RC_state[g_RC_timing_ptr])
    {
    // All we need to do is clear the pin and change its state to kWAITING
    if (g_RC_timing_ptr < 8)
    {
    bitclr (LATA, g_RC_timing_ptr & 0x7);
    }
    else if (g_RC_timing_ptr < 16)
    {
    bitclr (LATB, g_RC_timing_ptr & 0x7);
    }
    else
    {
    bitclr (LATC, g_RC_timing_ptr & 0x7);
    }
    g_RC_state[g_RC_timing_ptr] = kWAITING;
    }
    }
    //by :
    if (INTCONbits.TMR0IF)
    {
    // Turn off Timer0
    T0CONbits.TMR0ON = 0;

    // Clear the interrupt
    INTCONbits.TMR0IF = 0;

    // And disable it
    INTCONbits.TMR0IE = 0;

    // Only do our stuff if the pin is in the proper state
    if(g_ppm_enable)
    {
    if(g_RC_state[g_RC_next_ptr2] == kTIMING)
    {
    g_RC_state[g_RC_next_ptr2] = kWAITING;
    if(g_RC_next_ptr2==6)
    {
    g_RC_next_ptr2=0;
    }
    else
    {
    g_RC_next_ptr2++;
    g_RC_state[g_RC_next_ptr2] = kPRIMED;
    // Set the bit high
    if (g_RC_ptr < 8)
    {
    bitclr (LATA, g_RC_ptr & 0x7);
    }
    else if (g_RC_ptr < 16)
    {
    bitclr (LATB, g_RC_ptr & 0x7);
    }
    else
    {
    bitclr (LATC, g_RC_ptr & 0x7);
    }
    TMR0H = g_RC_Tmp >> 8;
    TMR0L = g_RC_Tmp & 0xFF;

    // Then make sure the timer's interrupt enable is set
    INTCONbits.TMR0IE = 1;
    // And be sure to clear the flag too
    INTCONbits.TMR0IF = 0;
    // Turn on Timer0
    T0CONbits.TMR0ON = 1;
    }
    }
    else if (g_RC_state[g_RC_next_ptr2] == kPRIMED )//after 300µS
    {
    // All we need to do is clear the pin and change its state to kWAITING
    if (g_RC_ptr < 8)
    {
    bitset (LATA, g_RC_ptr & 0x7);
    }
    else if (g_RC_ptr < 16)
    {
    bitset (LATB, g_RC_ptr & 0x7);
    }
    else
    {
    bitset (LATC, g_RC_ptr & 0x7);
    }
    g_RC_state[g_RC_next_ptr2] = kTIMING;

    TMR0H = g_RC_value[g_RC_next_ptr2] >> 8;
    TMR0L = g_RC_value[g_RC_next_ptr2] & 0xFF;

    // Then make sure the timer's interrupt enable is set
    INTCONbits.TMR0IE = 1;
    // And be sure to clear the flag too
    INTCONbits.TMR0IF = 0;
    // Turn on Timer0
    T0CONbits.TMR0ON = 1;
    }

    }
    else
    {
    if (kTIMING == g_RC_state[g_RC_timing_ptr])
    {
    // All we need to do is clear the pin and change its state to kWAITING
    if (g_RC_timing_ptr < 8)
    {
    bitclr (LATA, g_RC_timing_ptr & 0x7);
    }
    else if (g_RC_timing_ptr < 16)
    {
    bitclr (LATB, g_RC_timing_ptr & 0x7);
    }
    else
    {
    bitclr (LATC, g_RC_timing_ptr & 0x7);
    }
    g_RC_state[g_RC_timing_ptr] = kWAITING;
    }
    }
    }

    //in void UserInit(void) after :
    g_ack_enable = TRUE;
    //add :
    g_ppm_enable = FALSE;
    P_tick_counter = 0;
    g_RC_next_ptr2 = 0;
    g_RC_Tmp=60779;//300µS 65535-3567

    //in void parse_packet(void) after :
    case ('C' * 256) + 'U':
    {
    // For configuring UBW
    parse_CU_packet ();
    break;
    }
    //add :
    case ('P' * 256) + 'P':
    {
    // PP send rc ppm
    parse_PP_packet ();
    break;
    }

    //after :
    parse_CU_packet(){}
    //add :
    //Send 9 channel througt ppm
    // PP,B,1,500,500,500,500,500,500,500,500,500\r\n
    void parse_PP_packet (void)
    {
    unsigned char port;
    unsigned char pin;
    unsigned int value;
    unsigned int i;

    port = extract_number (kUCASE_ASCII_CHAR);
    pin = extract_number (kUCHAR);

    g_ppm_enable=TRUE;
    if (pin > 7)
    {
    bitset (error_byte, kERROR_BYTE_PARAMATER_OUTSIDE_LIMIT);
    return;
    }
    if ('A' == port)
    {
    port = 0;
    }
    else if ('B' == port)
    {
    port = 8;
    }
    else if ('C' == port)
    {
    port = 16;
    }
    else
    {
    bitset (error_byte, kERROR_BYTE_PARAMATER_OUTSIDE_LIMIT);
    return;
    }
    g_RC_ptr=pin + port;

    for(i=0;i<9;i++)
    {
    value = extract_number (kUINT);
    // Bail if we got a conversion error
    if (error_byte)
    {
    return;
    }

    // Max value user can input. (min is zero)
    if (value > 29725)//2.5ms
    {
    bitset (error_byte, kERROR_BYTE_PARAMATER_OUTSIDE_LIMIT);
    return;
    }
    if(value < 5945)//0.5ms
    {
    bitset (error_byte, kERROR_BYTE_PARAMATER_OUTSIDE_LIMIT);
    return;
    }

    // Now get Value in the form that TMR0 needs it
    // TMR0 needs to get filled with values from 65490 (1ms) to 53600 (2ms)//5945=0.5ms

    value=65535-(value-(65535-g_RC_Tmp));

    // Store the new RC time value
    g_RC_value[i] = value;
    // Only set this state if we are off - if we are already running on
    // this pin, then the new value will be picked up next time around (19ms)
    if (kOFF == g_RC_state[i])
    {
    g_RC_state[i] = kWAITING;
    }
    }
    print_ack ();
    }

    then compile and upload your file in the ubw.
    ;)
    http://www.schmalzhaus.com/UBW/FW/D_145/D_145.zip
  • no it just that my english to french joke converter is not working very well... ;)
  • ? sorry I didn't understand the joke...

    well it'll work for you, same as my spektrum signal.
    I'm sure there'll be lot of people following, in one hand you have a PCTx at 50$ on the other an 25$ interface that'll do the same... and even more.
  • Yes similar, you only have to know if it is positive or negative PPM signal and adjust the timing, some tx have 300µs of start pulse, some other have 400µs...
  • hello,
    the fact is that I added lot of different functions to my UBW code (stepper motor interface,laser driver interface, i2c, ...), and I'll share the code of this interface if wanted, the other part of my code is useless for drone.
    this part of my code will work on any UBW basic code version.
  • I can share this specific part of my code, but not my full custom ubw code.
  • Can you share the code?
This reply was deleted.