[Project] Automatic randomly timed MX start: problems

Status
Not open for further replies.

Llama16

Newbie level 4
Joined
Aug 30, 2014
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
87
Hello everyone,

If this is the wrong forum: apologies, but I couldn't find a more appropriate one.

I did my bachelor in electrical engineering, but now master in a different engineering field. they once let us play with a PIC microchip, and only changing some variables in a premade template. Years later, I decided to start programming a PIC16F690 for a personal project. I've been busy for days trying to figure everything out. So pls don't shoot me when asking stupid questions. This is a 'from zero' beginner.

OBJECTIVE:
This might turn into a build thread later on. Thing is, I do motorcross and I would like to build a automatic startgate.
The working of the gate has to be the following: set up manually. Once on bike press a button on a remote, this triggers a 10 second red warning light on the startgate. Once the 10 seconds are up, a red light flickers for 5 seconds followed by a 1 sec buzzer and after that the gate gets dropped (with a 9V solenoid pushing (for 1 second) the release) between 3 and 6 seconds RANDOMLY after the flickering light.

I've already programmed the PIC with a pickit 2, it simulated perfectly. Oscillator is set correctly, registers should be correct,... Point is, on the computer it works. But this has to transfer to hardware .
I've used MPLAB with XC8 compiler and wrote it in C. A review is always welcome . **broken link removed** or attachment

I made the hardware scheme, with some small corrections by a friend. Here's how it looks like: See picture or attachement.



For the wireless part I have a cheap ebay 'garage controller'. Here is a list of all the used parts. I can only order from farnell. **broken link removed** or attachment

Today I've carefully made everything on a breadboard. And thus far I'm satisfied that it partially works. Here is what has to be solved, and really need your help with. I've been staring at it for hours and after this solo project, I'm ready for some outside help:

STATUS:
The input pin is kept low when the 9V battery is connected. After this the green 'on' light goes on, which it should. BUT the solenoide is also continuisly on (as soon as 9V is connected which draws alot of mA), which is not part of the plan. When setting the input to logic high by the 10k resistor (to avoid a floating state), the red light goes on as it should, it also flickers after 10 seconds for 5 seconds as it should. Also the buzzer goes off for 1 second as it should. Then (the random timing I suspect) a couple seconds later, the solenoid turns OFF and stays off. As you see this is ALMOST the reverse of the what the solenoid should do.

This was problem one. Then I have a second one: There is no way for it to do this for more than one cycle. I always have to replug the 9V battery to make it do this. This is what happens when I retrigger the input after 1 cycle: The leds work as they are supposed to, but the buzzer 'clicks' (like putting a DC on a speaker) AND the solenoid does nothing. This happens every retrigger I try after the first cycle. To avoid this I need to replug the 9V battery in, which is quite impractical.

PROGRESS1: I think I've figured out most of the problem. I was using a cheap 9V battery. I decided to use a second one and run the solenoid and buzzer on that one. This helped. Now the device can go through the cycle many times: the buzzer now always goes and the solenoid operates.

Still 2 problems persist: when hooking up the solenoid is still continuilsy on untill I've gone through the first cycle.

Problem 2: After a while the timers start to stretch out: The leds blink slower and the time seems prolonged on every timer?? this baffles me. Because I can't see a draining battery affect the internal oscillator of the PIC.

I also have a suspicion that the random timer isn't random but constant. Does the PIC support rand()?

PROGRESS2: when hooking up 18 volt, the leds and timers are faster. Now I really don't know anymore

---

I'm pulling my hairs out. I'm not the kind of guy to come for 'easy' advice, and like to try everything myself first, but this got me puzzeled and I can really use some advice.

Kind regards,
Dries Coppens
 

Attachments

  • StartgateV1.X.zip
    302 KB · Views: 116

I note that you are calling the function RunCountdown() from the interrupt service routine which is not recommended - you should keep your interrupt service routines as short as possible because you may be missing interrupts - this could give the effect of timers appearing to stretch out
the interrupt service routine can use a flag (a global variable) to signal when an interrupt has occured that can be checked by the main loop, e.g.
Code:
int timerInterrupt=0;
void interrupt isr()
{
    
    if (INTCONbits.INTE & INTCONbits.INTF) /* external interrupt flag, wireless signal*/
    {
        timerInterrupt=1;
        INTCONbits.INTF = 0; /* Clear Interrupt Flag 1 */
    }
}
and in main()
Code:
    while (1){
        if(timerinterrupt)
             { timerinterrupt=0; RunCountdown(); }
    };
it would be a good idea to put some printf() statements in RunCountdown() to see what the values of your variables are doing - the algorithm may not be doing what you expect, e.g. the time counts may be getting longer and longer

rand() is a pseudo random generator - if the start seed is always the same you get the same random sequence
https://www.cplusplus.com/reference/cstdlib/rand/

this is often overcome by seeding it (using the function srand()) with time of day which is not possible in an embedded system unless you have an internet connection or similar
I would suggest writing the current rand() to an FRAM or barrery backed SRAM and seeding from that on startup
 
Thank you very much for your feedback. I will take into account your interrupt advice. It is allowed to miss interrupt though, as it should neglect any interrupt while it is still in the cycle triggered by the previous interrupt.

I have fixed alot of my problems by using a new IC DC voltage regulator. The last one was a bad batch I think because when (literally just) replacing it by another IC, the output voltage was constant, the solenoid works all the time and so does the buzzer. Also the LEDs have the a constant brightness.

AND: I think I no longer have any effect of the slowing/speeding down/up of the timers. They appear to remain constant going through many cycles.

Secondly: I think the rand() is indeed random (I also recently came across the srand(time) argument and I was about to implement it with srand(some sort of counter from bootup), but now when I time the solenoid responses, they seem to be random between the given interval. Is this possible

The only problem that still remains is that on bootup, the solenoid is constantly on, untill it goes through the first cycle and is explicitly said to turn off. How come that the output of that port is set to high when I plug in the 9V battery?

Already, many thanks! You've helped me alot.

EDIT: I've timed the constant timers and it's spot on with a stopwatch. The random timer (between 3 and 6 seconds), I have some values, they seem random even though I didn't use srand?:
5.72
3.19
5.50
3.07
4.61
3.00
3.99
3.6
4.86
4.84
5.36
3.01
3.47
5.33
3.84
3.26
5.70
 
Last edited:

don't assume anything on startup - e.g. with respect to the solenoid etc when you initialised the TRIS bits set the corresponding data bits to 0 or 1 as required - this ensures they are in the state you require for initialisation

every time you run do you get the same random sequence?

not sure about srand(time) - how do your get the calendar time on an embedded system?
somehow you need seed rand() with a different value on startup - possible your solenoid response will work OK

use the ADC to read the battery voltage and use some of the low bits as a seed?

there is plenty of discussion on the web about random number generators, e.g. use a noise generator into an ADC
http://world.std.com/~reinhold/truenoise.html
 

This sequence was just from a couple of cycles that I tested. I was also thinking of white noise indeed, or maybe a counter that starts from bootup and overflows. But that seems like something easy to implement.

So if I give it 0 at bootup, it should go away. It's just 'by accident' that it chooses to be high at bootup?

Also, how exactly do I use the srand(seed) function, in some examples I saw that they just call it up right before they call up rand()
 

So if I give it 0 at bootup, it should go away. It's just 'by accident' that it chooses to be high at bootup?

Also, how exactly do I use the srand(seed) function, in some examples I saw that they just call it up right before they call up rand()
It depends on what the device digital outputs default too on startup (I guess the device data manual would tell you) - I always make sure by setting outputs to what I require on initialisation
generally you would call srand() once at startup with a seed - if don't call srand() it will use some initial value
if you run the program again and again with the same seed you will get the same pseudo random number sequence (this is why it is called pseudo random) - on a PC I usually use time to seed it
the standard C/C++ random number generator is not very random (although OK for many applications) - if you do a web search you will see plenty of discussion and code for better generators
 

Thanks for your help, I think I can manage the rand() and srand() now.

RB4 was the only gate left that I forgot to initialise and give it 0 output! Thanks, I really didn't spot that.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…