Suggestions/opinions on my program

mackingu

New Member
This is a program I came up for a device meant as a sort of gift for my former boss. It spits out a user defined number of gumballs (he's the R&D manager at a confectionary company). Eclectic pointed out in another post (http://www.picaxeforum.co.uk/showthread.php?p=66396#post66396) a few oversights that I made with regards to the original program. One concern of mine is the counting of the gumballs after they've been dispensed.

After determining how many gumballs have to be dispensed, the motor is turned on. As gumballs pass out a shoot, the voltage change is recorded by a light dependent resitor and the number of times this occurs is compared to the the number of gumballs that should be dispensed. Once the two values are equal, the motor shuts off. Does anyone think this is an appropriate method? I haven't been able to come up with anything better, so some input would be great.

Thanks

-mack


Code:
'08M gumball/jawbreaker dispenser program


symbol trimpot = 1				'leg 6 
symbol trimpot_value = b1
symbol pbutton = pin3				'leg 4
symbol supposed_to_dispense = b2
symbol pressed = 1
symbol count_LDR = b3
symbol dispensed = b4
symbol LDR_pin = 4				'leg3
symbol LDR_value = b5 


pwmout 2 off					'make sure the motor isn't on yet


read_trimpot:
	readadc trimpot, trimpot_value	'read trimpot and put value into memory
	goto button_press			


button_press:
	if pbutton = 0 then to_b_dispsensed	'if button is pressed goto main and dispensed gumballs/jawbreakers
	goto read_trimpot			'if button is not pressed read trimpot and check for button press


to_b_dispsensed:

	if trimpot_value < 26 then 
	let supposed_to_dispense = 20
	goto main
	endif
	
	if trimpot_value < 51 then 
	let supposed_to_dispense = 40
	goto main
	endif
	
	if trimpot_value < 77 then 
	let supposed_to_dispense = 60
	goto main
	endif
	
	if trimpot_value < 102 then 
	let supposed_to_dispense = 80
	goto main
	endif
	
	if trimpot_value < 128 then 
	let supposed_to_dispense = 100
	goto main
	endif
	
	if trimpot_value < 153 then 
	let supposed_to_dispense = 120	
	goto main
	endif
	
	if trimpot_value < 179 then 
	let supposed_to_dispense = 140		
	goto main
	endif
	
	if trimpot_value < 204 then 
	let supposed_to_dispense = 160		
	goto main
	endif
	
	if trimpot_value < 230 then 
	let supposed_to_dispense = 180
	goto main
	endif
	
	if trimpot_value < 255 then 
	let supposed_to_dispense = 200	
	goto main
	endif


main:	
	pwmout 2,99,4				'turn motor on
	readadc LDR_pin, LDR_value		'checks if gumball has passed and start comparing
	if LDR_value > 50 then let count_LDR = count_LDR + 1
		goto count_pballs
	else 
		goto main
	endif	

count_pballs:
	let dispensed = count_LDR
	if dispensed < supposed_to_dispense then goto main
	pwmout 2 off
 
Last edited:

mackingu

New Member
*bump*

No suggestions? Is it wishful thinking to believe that my program works as well as it ever will get or is it that no one is interested? :D
 

Mycroft2152

Senior Member
Hi Mack,

Here's my 2 cents.

You may have problems with the sensitibty of the pot in setting the count. It all depends on the type of pot used. Since you are counting groups of 20 gumballs. using a 20M would let you digitally set the number with toggle switches

Adding an LCD to show the count and status would be very impressive and not that expensive.

This is more of a mechanical project than a Picaxe. Feeding and stopping the gumballs and preventing jams in the counter is going to be more of a challenge.

I saw on a "how it's made" type TV show that they counted paintballs using a rotating disk with the correct number of holes around the circumference. the paintballs dropped into the holes, then dropped out into the packaging bin 180 degrees later.
 

mackingu

New Member
Thanks for your suggestions Myc; I see your point about it being more of a mechanical problem.

I thought of the 20M, but Rev-Ed doesn't have a distributor in Canada that sells them. After the 08M I can go with the 14M or 18X, so I settled with the 08M. If I had the extra port(s), I'd do a parallel LCD, but I'll save that for another project.

As for the jamming, I don't think it'll be that big of a problem as I'm essentially doing the paintball method you mentioned. In fact, paintball is where I got my inspriation - I looked at the inside of my buddy's agitated paintball hopper and got my idea from that :D
 

hippy

Ex-Staff (retired)
There's a potential timing issue as you check for a gumball, count it and then check for another. I don't know how fast your gumballs are going but you could be back to check and count the same ball twice. The program's logic is also a little confusing ...

Code:
dispense = ?
PwmOut 2,99,4
Do While dispense > 0
  dispense = dispense - 1
  Do
    Readadc LDR_pin, LDR_value
  Loop While LDR_value > 50
  If dispense = 0 Then
    PwmOut 2 Off
  End If
  Do
    Readadc LDR_pin, LDR_value
  Loop Until LDR_value > 50
Loop
 

mackingu

New Member
Thanks for the code hippy. Counting the paintballs was the biggest concern I had when writing this program - whether or not I would miss a gumball/jawbreaker was what I was thinking - but I didn't foresee the problem that you found! I've never used a command like the Do...Loop function (it's not mentioned in the David Lincoln book), so being unfamililar with it I decided not to bother with it. But your example provides much needed clarity in its use. Groovy.

As an aside, one of the reasons I choose an 'axe versus using a PIC or Stamp (aside from ease-of-use and cost) was because the members on this forum kick so much butt in terms of offering solutions and general help.

Thanks guys!

-mack
 

mackingu

New Member
Hmm... It seems as though the Do...Loop functions provided in your code has thrown me for a loop. Pardon the pun :D Could you clearify how it works exactly? I'm having one helluva time trying to figure out how to use it with my existing code.
 

crossthreaded

New Member
I hope your confidence in the mechanical part of this project is justified, that's where the time goes in my experience.

Your program. Well, it does things in the right order.

I agree with hippy about the reliable counting problem. There are two issues, one concerns using a fixed threshold and the other is the double count problem.

A fixed threshold works if you can control the lighting conditions completely, i.e. in this situation, excluding outside light and internal reflections.

The double count problem is harder. I think you may need to look for the occlusion of the detector increasing and then decreasing before you count a ball as being dispensed, this might be possible with two thresholds, but I've done a similar thing in the past with an adaptive algorithm which looks for suitably sized peaks in the sensor output (This was for a responsive Christmas tree decoration, also on the 08M).

The program only runs once, you have to power cycle before it will run again.

The "case" statement for the number to dispense is huge (in 08M terms), could you approximate it by taking the pot reading, divide by 20 and then multiply by 20 again? this would give a very similar result in 3 lines of code. Also the current code fails if the input is 255 exactly.

Sounds like a fun project though.
 

mackingu

New Member
Delete everything you have after "main:" and insert the code there.
That's what I tried last night and it didn't work. It didn't hit me until right now that the variable "dispense" that you used should be "dispensed" (which I defined) and it should be compared to the variable "supposed_to_dispense." Whoops :)

It seems that fixed the problem. Thanks again!
 

mackingu

New Member
I hope your confidence in the mechanical part of this project is justified, that's where the time goes in my experience.
This is the one thing I'm relatively comfortable with. My only concern here is coming up with a cheap way to stop the gumballs from falling out. I used my buddy's paintball hopper as inspiration for this, and to prevent paintballs from continually dropping out, they're stopped when the bolt of the marker is closed. Unfortunately, I don't have anything like that. I was thinking of using a solenoid to open/close a door when the machine is supposed to dispense, but the only ones I can find are rather pricey and bulky, not to mention they need 6V or 9V and I'm planning on making this thing run on 5V only.

Your program. Well, it does things in the right order.
That's a first :D

A fixed threshold works if you can control the lighting conditions completely, i.e. in this situation, excluding outside light and internal reflections.
The bucket and shoot will be made from an opaque plastic that's safe to use for food storage so that shouldn't be a problem. Raw gumballs/jawbreakers or gumballs out of the grossing stage aren't reflective so that isn't an issue. And finished gumballs shouldn't be much of a problem in terms of their reflective surfaces either.

...I've done a similar thing in the past with an adaptive algorithm which looks for suitably sized peaks in the sensor output
I'd appreciate it if you'd be willing to share the code here.

Sounds like a fun project though
It was for a while. :p
 

crossthreaded

New Member
I just went back to look at the code and it was kind-of very involved with the way I read an LDR.

The original project was to detect light changes (really, really subtle light changes) as a proximity alarm, based on a low-power application, which had to run on a button cell over two weeks (Christmas). To remove all the noise from the reading, including reading jitter resulting from random offsets in some of the timers, I took 10 readings off the ldr, calculated the min and max over this time period, then used these dynamic thresholds to decide whether any interesting light level changes were taking place. It was neat because it had massive dynamic range, low power and could detect someone walking down a corridor up to 6 feet away. I'd love ot have time to tidy up the code right now and post it in a useful form, but it was being developed in a bit of a hurry - I'd have to publish the circuit diagram too because of the devious way I read the ldr without a voltage devider draining power all the while.

I think a system of two threshold should be enough. Just look for the dark patch when a ball goes through and then a light patch before you count it. You may need to set the hardware up and measure the light level receiver output to set the thresholds correctly.
 

BCJKiwi

Senior Member
No idea what the current mechanism looks like but there is an alternate way to handle the feed and the count.

If the hopper feeds into a tube, then a disk with notches in the periphery is mounted at right angles to the tube so that a ball falls into the notch when the notch is under the tube.

The disc is turned by a stepper motor so the feed and the number of balls dispensed is controlled by the number of notches you pass under the tube.

As the disc turns the ball falls out once clear of the input tube down whatever output chute you want.

There are many variations on the input/output/notch orientation available depending on how you want it all to happen.

this type of mechanism is now the most common in all sorts of automated feeders form bottling plants to assembly systems.
 

mackingu

New Member
No idea what the current mechanism looks like but there is an alternate way to handle the feed and the count.

If the hopper feeds into a tube, then a disk with notches in the periphery is mounted at right angles to the tube so that a ball falls into the notch when the notch is under the tube.

The disc is turned by a stepper motor so the feed and the number of balls dispensed is controlled by the number of notches you pass under the tube.

As the disc turns the ball falls out once clear of the input tube down whatever output chute you want.

There are many variations on the input/output/notch orientation available depending on how you want it all to happen.

this type of mechanism is now the most common in all sorts of automated feeders form bottling plants to assembly systems.
http://www.viewloader.com/product.php?pid=8035&cid=18

The dispensing mechanism that I had envisioned is similar to the picture in the lower right-hand corner, but would dispense 5 balls/rev instead of 6. It's very similar to what you have described.

I originally planned to use a stepper, what way I would know how many revs - and thus the number of gumballs dispensed - but I haven't been able to find any cheap enough or small enough. I figured I'd use a gearmotor like the ones from Solarbotics driven with PWM.
 

BCJKiwi

Senior Member
Continuous is more common but the stepper adds the possibility of the count without separate sensors.

23BPS is pretty fast! Are you building a paint gun or a gumball dispenser??:)
 

mackingu

New Member
Continuous is more common but the stepper adds the possibility of the count without separate sensors.

23BPS is pretty fast! Are you building a paint gun or a gumball dispenser??:)
My bud has been bugging me to make him a paintball dispenser ever since I came up with the idea for a gumball dispenser. The problem is, a paintball dispenser will allow him to shoot me more often! :p
 

mackingu

New Member
You could do something similar with groups of 20 "slots" and rotate the disk to get the correct fill.

Myc
Great link! Unfortunately, I can't use that method for what I believe will be its intended purpose.

When I worked at the candy factory a problem arose where there was always a difference between expected weight and final weight of the gumballs. We'd take a gumball/jawbreaker at various stages of doneness and weigh them knowing that there should be x number of balls for y amount of weight. But we'd use small samples and do them infrequently because of time constraints which lead to errors. With the dispenser, larger quantities of balls can be measured, and more frequently, thus giving a closer number to the true mean.

Oops, went off on a tangent. Anyhow, the paintball hopper method will work best IMO because it can be used for a variety of gumball sizes and at various stages of doneness. The only thing it won't do are the mega jawbreakers - they're about the size of a baseball and 450g each!
 

crossthreaded

New Member
A final thought for now. There's no error recovery if you run out of balls - the motor will run forever.

You could add some approximate timing in the sensor loop and decide something was wrong after 10 seconds with the motor running without seeing a ball. This would stop the motor on jams as well as running out.
 

mackingu

New Member
A final thought for now. There's no error recovery if you run out of balls - the motor will run forever.

You could add some approximate timing in the sensor loop and decide something was wrong after 10 seconds with the motor running without seeing a ball. This would stop the motor on jams as well as running out.
Or just use the counter - if it keeps counting nothing shut down.
This will come as soon as I can build the darned thing and test it out to see if the whole contraption actually works. I also have to figure out how to reduce the IF statements with a snippet provided by CT to free up some room for the extra code. :D

Cheers
-mack
 

BCJKiwi

Senior Member
The to_b_dispensed section of if statements can be replaced by;

Code:
trimpot_value = trimpot_value / 25 +1  'results in 1 thru 10
supposed_to_dispense = trimpot_value * 20    'results in 20 through 200
 
Last edited:

mackingu

New Member
That's similar to what was provided by CT but it looked so simple and straightforward that I thought I was doing something wrong with it. :p

Will update when I get my next paycheque to pay for the needed parts.

-mack
 

BCJKiwi

Senior Member
Missed CrossThreaded's solution but yes this is basically the same;
A little further explanation:- divide by 25 as that is the size of the steps in the if statements, * 20 as that is the step size for the outputs, +1 as 24/25 will produce 0 due to integer math.
 
Last edited:
Top