Hello all! I am brand new to this forum and I'm looking to get help programming in assembly. I have an idea put together for a drink mixer machine in my bar/man cave area in my basement and I would like to have it electronically controlled using an 8051 microcontroller. I already have the program algorithm put together in a manner that I think will work but I have very little knowledge on how to actually translate it to any language. I've done some JAVA, C, and assembly in the past but I am no where near proficient enough to successfully code my program.

I'm running PROVIEW32 for my compiler/assembler and I'm running it on Windows XP 32-bit.

What the device does is control a series of solenoid valve that allow/deny liquid slow from a separated set of bottles. I plan on being able to mix drinks for friends and have it set back built-in to the back shelving. You press a single button for a specific drink and the machine fills your cup with the corresponding, pre-programmed liquid mixture. It's really exiting, I've seen similar ideas done before and it seems like an awesome project. I have a prototype built with most of the wiring done and I've tested the outlet tubes for each bottle and it works great so far. My first design is to mix four bottles, here is the algorithm I have thus far:

  /initialize main program


initialize inputs:

mix_drink_button_0 = p1.0  /program addresses certain inputs/outputs to different i/o ports on the microcontroller
mix_drink_button_1 = p1.1
mix_drink_button_2 = p1.2
mix_drink_button_3 = p1.3
mix_drink_button_x = px.x  /add as many mix_drink_button's as you need for output for future modular expansion


initialize outputs:

solenoid_valve_0 = p2.0  /program addresses certain inputs/outputs to different i/o ports on the microcontroller
solenoid_valve_1 = p2.1
solenoid_valve_2 = p2.2
solenoid_valve_3 = p2.3
solenoid_valve_x = px.x  /add as many solenoid_valve's as you need for output for future modular expansion

lcd_screen
lcd_screen_outputs  /program code for lcd screen



input_scanner_loop:  /program stays in input-scanning loop until drink_mix_button 0, 1, 2, or 3 is pressed, then jump to corresponding mix_drink_subroutine

if mix_drink_button_0 = 1
jump_to mix_drink_subroutine_0

if mix_drink_button_1 = 1
jump_to mix_drink_subroutine_1

if mix_drink_button_2 = 1
jump_to mix_drink_subroutine_2

if mix_drink_button_3 = 1
jump_to mix_drink_subroutine_3

    jump_to: input_scanner_loop



mix_drink_subroutine_0:

store_solenoid_valve_#: x = 0  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

store_solenoid_valve_#: x = 2  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

    jump_to: input_scanner_loop


mix_drink_subroutine_1:

store_solenoid_valve_#: x = 1  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

store_solenoid_valve_#: x = 2  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

store_solenoid_valve_#: x = 3  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

    jump_to: input_scanner_loop


mix_drink_subroutine_2:

store_solenoid_valve_#: x = 0  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

store_solenoid_valve_#: x = 1  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine


store_solenoid_valve_#: x = 3  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

    jump_to: input_scanner_loop


mix_drink_subroutine_3:

store_solenoid_valve_#: x = 0  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

store_solenoid_valve_#: x = 1  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine
store_solenoid_valve_#: x = 2  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

store_solenoid_valve_#: x = 3  /store predetermined solenoid valve number in memory location x, x = valve number
store_solenoid_valve_time: y = ?  /store predetermined amount of time in miliseconds in memory location y

jump_to: activate_solenoid_subroutine

    jump_to: input_scanner_loop



activate_solenoid_subroutine:

get_solenoid_valve_#: x = solenoid_valve_x  /get solenoid valve number from memory location x, set x as valve number
open_solenoid_valve_x: solenoid_valve_x = 1  /enable solenoid valve solenoid_valve_x, where x is the valve number
jump_to: time_delay_subroutine

close_solenoid_valve_x: solenoid_valve_x = 0  /disable solenoid valve solenoid_valve_x, where x is the valve number

    jump_to:



time_delay_subroutine:

count_down_delay = y /predetermined amount obtained from above

    jump_to:


  /end of main program


After this I'm stuck. I've coded simple programs using this microcontroller and PROVIEW32 before, but nothing this complicated. How would you guys translate this to something that could be assembled and uploaded to the MC? Any and all help will be greatly appreciated!! In the mean time I'm going to try drilling further into this ASM programming manual I have at my desk. Thanks!
Posted on 2011-10-10 19:20:51 by nikolia982003
Does anyone have any clues on how to help me on this? Did I say something wrong? :( I'm new here, I'm sorry.
Posted on 2011-10-15 09:46:02 by nikolia982003
You said nothing wrong.  In fact, I liked your idea!  :D
However, getting help on programming an 8051, even in this community, may be slim pickings.
Posted on 2011-10-15 20:01:23 by p1ranha
Ohh... Do you guys have a better piece of hardware I might want to use? since posting this I've learned a little about arduinos, I think this make work better. They seem to be based off similar tech, but have their own programming language which is easier for newcomers. I'm considering getting the uno board, it seems to be the most popular, what do you guys think?
Posted on 2011-10-23 05:35:18 by nikolia982003
I have an Arduino (plus a couple bootloaded chips), and I'd say that's the way to go.  The Arduino IDE uses an extension of C, and there's a HUGE fan base for it, so it would probably give you less trouble and much more support if you had difficulties.  Of course, AVR's can also be programmed in an assembly language too, which will take an AVR chip programmer.

The thing is that, unlike C or Java, most microprocessors/controllers have their own unique form of assembly, so x86 assembly programming is very different from 8051 programming.
Posted on 2011-10-23 12:24:40 by metallevel
I love the Propeller for experiments !!! definitely worth a look for anything hobby related, its probably more powerful than you need, but being able to upload new programs by USB or ethernet is priceless!
Posted on 2011-10-23 22:54:43 by Homer
The Arduino "programming language" is just C++ with a little initialization code that gets inserted. If you don't like the Arduino initialization code getting in your way, you'll find that most AVR freaks use either GCC built for AVR (like WinAVR) or the free Avra assembler. If you are interested in learning more about AVR's or just want to search over some of the project archives, you should check out the AVR Freaks Website.
Posted on 2011-10-23 23:45:25 by Synfire
Does it have 8 cores? Oh.
Posted on 2011-10-25 06:12:35 by Homer
The thing is that, unlike C or Java, most microprocessors/controllers have their own unique form of assembly, so x86 assembly programming is very different from 8051 programming.
I think any assembler lang vs any high level lang is very different, but any assembler vs any other assembler not so much.
For example, this program, sounds trivial to me; basically a single table lookup with some  port control.
From someone who has never worked with a MC, never read/wrote any 8051 asm before, here is what I came up with (just by skimming through a ref manual. I didn't download any emulator for this):

; P1 input
; P2 display
; P3 valve control
MAX_NUM_OF_DRINKS equ 4; number of rows
NUMBER_OF_LIQUIDS equ 4; number of columns
TABLE_ROW_SIZE equ NUMBER_OF_LIQUIDS*1; all data is byte
DELAY_MULTIPLIER equ 1234; calculate it yourself
cseg at 0
ljmp Main
Main:

waitLoop:
mov A, P1
jz waitLoop;

; check for for illegal input ( A>MAX_NUM_OF_DRINKS )
CLR C; clear carry
mov B, A
subb A,MAX_NUM_OF_DRINKS
jnc waitLoop

dec B; make B zero based index

mov P2,#1 ; signal/print working...

; calc table row offset
mov A,TABLE_ROW_SIZE
mul AB

; set data pointer
mov DPTR, #table

; our number of liquids value
clr R0
repeatLoop:

push A; preserve row offset

; get table row data
movc A, @A + DPTR
jz timeIs0

;if time not 0 {
mov P3,R0 ; signal open valve N

; make delay
mov B,DELAY_MULTIPLIER
mul AB
delay:
djnz A, delay

mov P3,R0 ; signal close valve N
; }
timeIs0:

pop A; restore row offset
inc A; for single byte data -> inc by 1

inc R0
cjne R0, #NUMBER_OF_LIQUIDS, repeatLoop

mov P2,#0 ; signal/print finished

ljmp Main
table:
        ; row 0 - drink 1
; L0, L1, L2, L3, ..., Ln - time for each liquid , 0 = do not pour
db 2, 0, 1, 0
; row 1 - drink 2
db 5, 4, 2, 0
; row 2 - drink 3
db 1, 3, 3, 4
; row 3 - drink 4
db 1, 0, 2, 0
;etc.
        end

NOTE: THIS IS CODE IS NOT TESTED!

So instead of adding code for more drinks, just add a single row of data and change 1-2 equates.

Posted on 2011-10-25 13:19:56 by drizz