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
  • lol...sorry guys.......

    Just been working all night, brain befuddled....i forget that things get lost in translation..

    keep up the passion...erm...work...

    Mike. :~)
  • Admin
    Roman, Not to worry, my converter doesn't work either :)) Love of technology is universal passion.
  • no it just that my english to french joke converter is not working very well... ;)
  • Admin
    & not so clever becons like me too. I belong to " many " who are interested and promise to be a good student. Thanks
  • Roman,

    it was a joke, dont take it personally, just my dry english humour (i forget that irony is wasted most of the time)

    More importantly, what you are doing is very good, and yes know the PCTx system, and figured that if somone has found a work-around, then MANY here are interested for sure.

    I for one, want to get away from the Tx system, so ...

    Please inform us of what your Open Source Hack is capable of, and the code so we can try this also.

    The effort you put in here, comes back to you with the support of summet like 10k members (last time i looked (Moderator)) taking everything to the next level, and the next etc...

    There are some very clever sauseges in this community!

    Mike,
  • ? 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.
  • system im running is neg ppm and 400us...

    You going to share your toys with the rest of the children? :~)

    Mike.
  • 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...
  • shame, looks pretty cool..and interested in getting into somthing similar, (not spectrum though) but the theory is similar..

    Gampad -> PC/laptop ->Tx

    Open source all the way!

    Mike,.
This reply was deleted.