Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Need help with complicated code...

Status
Not open for further replies.

dmccormick001

New Member
I need some help, please! I'm trying to modify a really nice program provided by PicProjects.org for navigation lights on an R/C model. The link to the project info ishere.

What I want to do is add some code to allow me to turn the lights on/off from the transmitter, by using the PULSIN command to detect the signal from the receiver. (As provided, the lights all come on as soon as the model is turned on.) But I'm not sure exactly where to insert the new code to do this, since this program uses several different files to execute. I think the best place to do it is at the very beginning of the file that's named "RCnavlights_func.inc", but I'm not sure. Can someone look at the files included in this project and advise me? My goal is to have the code check for a valid signal, something greater than 1.55ms, and if no signal is present, continue to check. If a valid signal is detected, then proceed as normal, which will casue the lights to come on.

Also, since I cannot program in "C", I'm hoping to be able to add my code in PICBASIC, and then cut and paste the provided ASM code into the program before I compile it. That's do-able, right?

Thanks in advance for any help you can provide! Sorry for the dumb questions, but I'm still re-learning this stuff. At 56, it doesn't come as easy as it did in my college days when I worked for Radio Shack!
 
Also, since I cannot program in "C", I'm hoping to be able to add my code in PICBASIC, and then cut and paste the provided ASM code into the program before I compile it. That's do-able, right?

I wouldn't have thought so - why not just write the entire program in PICBASIC? - the existing program is EXTREMELY trivial, your required mods are considerably more complicated.
 
What I want to do is add some code to allow me to turn the lights on/off from the transmitter, by using the PULSIN command to detect the signal from the receiver.

The firmware I downloaded was in Assembly, not C.

Is the PULSIN command a C instruction or for the transmitter you are using. The usual way to work a receiver switch is from a transmitter switch, e.g., smoke or kill are switches.

It should not be that difficult to initiate this program from a transmitter switch in a similar way as smoke is turned on. What transmitter and receiver are you using? How many channels?

John
 
I've modified the code to do what I understand you want (use attached file)

At start-up the code waits for an active high pulse > 1.55mS on GPIO4. Once it sees a pulse >1.55mS it runs normally.


I've not been able to fully test it because I don't have a means to generate the servo pulse handy and it's too late to mess around so I'd be grateful for your feedback as to whether it does what you want.
 

Attachments

  • RCnavlights_main.HEX
    4.3 KB · Views: 110
Last edited:
Nigel: With all due respect, I don't agree that the program is "trivial". It features a file that contains data (which you can modify yourself) which allows you to change the way the outputs behave, and you can switch between modes while the program is running. Far more complicated than I am capable of writing using PICBASIC.

John: You're right, of course, the code is indeed in Assembly, not C. PULSIN is a command in PICBASIC, very useful for programming circuits for use with R/C models. It allows you to branch the program based on the position of a channel's switch, knob, or stick. I didn't want to use a dedicated switch because of extra weight, etc., and because I knew it could be done via the program itself.

Pete: Thank you so much! I didn't want to ask you to do something like this because I figure you get a ton of requests. I'll try the new program tonight and report back. By the way, you should lnow how much I've learned from the info you provide on your site. I pick it apart, experiment with it, and learn by trying various things and seeing how it affects the circuit. Probably learn as much from what doesn't work as what does. Would it be too much to ask for a copy the files that you changed, so I can see how you did it, where you put the new code, etc? It will teach me a lot by seeing how you did it, especially since the code is in assembly, which I don't understand as well as I'd like to.

David
 
Nigel: With all due respect, I don't agree that the program is "trivial". It features a file that contains data (which you can modify yourself) which allows you to change the way the outputs behave, and you can switch between modes while the program is running. Far more complicated than I am capable of writing using PICBASIC.

It's VERY easy in BASIC, use the DATA instruction to make a data table.
 
David,

Thanks for the info on PULSIN. I will need to read up on it. My approach would have been just to have a software timer monitor the servo channel and then respond accordingly as the pulse width changed.

John
 
It's VERY easy in BASIC, use the DATA instruction to make a data table.

This might work for a straight blinking light but that isn't what my code does. This is based on my RGB Mood light and uses a 3 channel 8 bit PWM to simulate a rotating beacon by slowly ramping up and down with a 'bright' flash as it is directed at you. By carefully setting up the data it also uses one of the other channels to provide the strobe. I didn't actually create the dataset to do this but the person who did shared it with me and the reason they used it was because a 'blinking LED' didn't cut it. I put it on my website as a specific projects and it has proved very popular precisley because it doesn't just 'flash' a LED on and off.

So I would dispute that it is trivial to reproduce the same functionality in BASIC, possible but not trivial.
 
Last edited:
@geko
Just a little nitpicking, there is a difference between navigation lights and anti-collision lights on an aircraft. Your solution offers both. Nicely done, though.

John
 
Would it be too much to ask for a copy the files that you changed, so I can see how you did it, where you put the new code, etc? It will teach me a lot by seeing how you did it, especially since the code is in assembly, which I don't understand as well as I'd like to.

David


David: I'm not sure if this does what you want since it only works at startup; it doesn't allow you to turn it off and on at will which is perhaps what you are looking for but I wasn't clear in your OP. Getting it to do that is much more difficult since the original code doesn't allow for any way of accuratley measuring the pulse.

The following code is inserted just before the final goto in the RCnavlights_start.inc file.
This sits just after the code initialises and before it jumps into the PWM loop for the first time.

Code:
              clrf	T1CON	; initialise timer 1 control
              
              btfsc	GPIO,4	; wait for GPIO4 input to go low
              goto	$-1
              
reset.pulse.measure
              movlw	LOW (.65535-.1550)	; preload timer 1 to measure 1.55mS
              movwf	TMR1L
              movlw	HIGH (.65535-.1550)
              movwf	TMR1H
              
              bcf	PIR1,TMR1IF		; clear timer 1 interrupt flag
              
wait.pulse.low
              btfss	GPIO,4		; wait until GPIO4 input goes high
              goto	wait.pulse.low
              
              bsf	T1CON, TMR1ON		; start timer 1
              
wait.pulse.high
              btfsc	GPIO,4		; wait until GPIO4 input goes low
              goto	wait.pulse.high
              
              bcf	T1CON, TMR1ON		; stop timer 1
              btfss	PIR1, TMR1IF		; if interrupt flag set the GPIO4 pulse > 1.55mS
              goto	reset.pulse.measure	; else it was <1.55ms wait for next pulse
              
              ; *** goto from original file ***
              goto            _pwmDriveHi       ; Go and run the main code
 
Thanks Pete. I tried the modified program, and it works great, but as you suspected, I was hoping to be able to turn the lights off again. Since the code you added is able to determine the presence of a signal greater than ~1.55ms, isn't there a way to use the same method to detect a signal of less than 1.55ms, and insert it into the code at a different place? The measurement wouldn't need to be very precise, anything less than 1.40-1.50ms would be accurate enough. If the lower pulse width were detected, it could set all the outputs low and then send the program back to the start of the code above (reset.pulse.measure) to begin waiting for the signal to go high again?

I'm still pondering all the files, trying to get it straight in my head how they all fit together (main.asm, start.inc, function.inc., data.inc, and tout.inc), and it looks to me like it should be possible to check the pulse width of the signal on GPIO4 after each time the code runs through one complete data sequence. That would be more than "quick" enough response, as the normal way it would be controlled would by flipping a switch on the transmitter.

Thanks for all your help, Pete. I've already learned a lot by studying the code. I really appreciate the time you're taking to do this.

David
 
Unfortunatley it isn't as simple as that, otherwise I would have done it in the first place.

The servo pulse is a 1-2mS pulse that occurs between 6-25mS and the interval between pulses is not predicatable. Since this is an external signal it is asynchronous to what the code is doing. We have no way of knowing where or when it will occur. The original code isn't interrupt driven and sits in a very tight loop generating the PWM signal, at the end of each period it pops off and does some other stuff. There is no point in the code to reference the measurement of the servo pulse.

I've come up with a way of doing it using the Timer1 gate control which in my head works and in the real world might too ;)

First thing about this method of detecting the servo pulse is that it requires an active low signal on the GPIO4 input so you will need to invert the servo pulse - a simple NPN tranistor should do the trick. Collector to GPIO4, Base via a 1K resistor to the servo input, Emitter to Ground.

I'm not at home this weekend so I've written the new code on my laptop but have no way to test it - I've been through it very carefully and can't see any mistakes for what it's worth. So again, try it and let me have some feedback.
 

Attachments

  • RCnavlights_servoL.HEX
    4.4 KB · Views: 103
Last edited:
I wonder if it would be feasible and/or practical to use a 6-pin 10F chip to monitor the servo signal and turn the sequencer chip on or off?
 
I wonder if it would be feasible and/or practical to use a 6-pin 10F chip to monitor the servo signal and turn the sequencer chip on or off?

That would work for sure.

I'm hoping that by using the servo pulse to Gate Timer1 we can accurately measure the duration of the pulse independant of the PWM code. As long as we check and reset the timer faster than the servo period it should work
 
Well, I tried the new HEX file and I can't get the circuit to do anything. I checked everything by going back to the previous file, and it works fine. But the new one won't come on at all. I tried it in every way I could think of, with the servo output high before I applied power, then low, etc. and no response.
 
...The servo pulse is a 1-2mS pulse that occurs between 6-25mS and the interval between pulses is not predicatable. Since this is an external signal it is asynchronous to what the code is doing. We have no way of knowing where or when it will occur. The original code isn't interrupt driven and sits in a very tight loop generating the PWM signal, at the end of each period it pops off and does some other stuff. There is no point in the code to reference the measurement of the servo pulse.
...

That is not insurmountable. Just monitor the servo input pin in your PWM loop, this only takes 2 instructions and 2 clock cycles;
BTFSC servo_pin
CALL clear_timer1

then elsewhere;
clear_timer1:
CLRF TMR1H
CLRFTMR1L
return

so the extra 2 clock cycles to monitor the pin shouldn't hurt your PWM output, and on the rare cases where the event is detected the extra few clock cycles to clear TMR1 are not going to affect your PWM significantly. If you put the test at the end of your PWM loop you can even reduce it to one ASM instruction;
BTFSS servo_pin

Then of course you need to do a similar thing to grab the TMR1 16bit count when you detect the \ edge of the servo input pulse. If you don't want the time overhead of having both tests in the one PWM loop then make two identical copies of the PWM loop, one for detecting the / edge and one for detecting the \ edge.

There will be some small errors in the detected period but as usual these can be reduced by averaging a few periods.
 
Well, I tried the new HEX file and I can't get the circuit to do anything. I checked everything by going back to the previous file, and it works fine. But the new one won't come on at all. I tried it in every way I could think of, with the servo output high before I applied power, then low, etc. and no response.

Okay, apologise for that, there was a single typing error in the code - bound to happen :mad:

The attached code does work and is tested. Still requires the servo pulse to be inverted using a transistor. RCnavlights_servoL2.HEX turns the outputs on/off at about 1.55mS

RCnavlights_servo3CH.HEX, turns the three outputs on successively at 1.25, 1.5 and 1.75mS
 

Attachments

  • RCnavlights_servoL2.HEX
    4.4 KB · Views: 97
  • RCnavlights_servo3CH.HEX
    4.4 KB · Views: 102
Last edited:
You are the MAN, Pete! I can't tell you how impressed I am with your willingness to modify a circuit like this just for me. Now, if I may be so bold as to ask one more favor, could you send me the files that you had to modify? Two reasons, #1 is so I can re-compile them using the data sequences I have already changed to suit me. (I eliminated a few I didn't need, and "tweeked" the others to give me the best look with the LEDs I'm using. I use the straw-hat LEDs for the beacon, it really looks good!) #2 reason is to study the code and see if I can understand what's happening. I have absolutely no formal training in electronics, no classes, no tutor, nothing, all I have ever had is what I can pick up by reading, looking at other people's code, and experimenting with it. I'll change something sometimes just to see if it works, and even if it doesn't I usually learn something by what is different, what changed. Anyway, if I could look at the code I think it would help me just to understand how all the .INC files work together to make the program work. I've never really seen a program for the 675/629 that uses so many clever ways to do so much at once, and I want to learn how you meshed them together to do it. It's without a doubt one of the most clever uses of the chip's capabilities I've ever seen, you should be quite proud of it!

Thanks so much, Pete. If I can ever help you out with anything (yeah,right!), just whistle. I owe you big time. Merry Christmas, and Happy New Year to you.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top