Check if O/P is high and others

Tasp

Member
Hey everyone, great forum,

Very new to PIC's and PICAXE, so please don't hurt!

The concept is to use the PIC as a 3 to 8 decoder ie. (74HS138) however I need the PIC to latch until the input pulses again,
So 1st pulse turn output on, 2nd pulse turn output off, simple!
(inputs 0 to 3 are binary so a combination activates the relevant output)

Here's the code I've made.
Code:
TOP:           '1            2            4            8
IF PORTC PIN0 = 1 AND PIN1 = 0 AND PIN2 = 0 AND PIN3 = 0 AND b0 = 0 THEN HIGH PORTC 4 : LET b0 = 1 : ENDIF '1
IF PORTC PIN0 = 0 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 0 AND b1 = 0 THEN HIGH PORTC 5 : LET b1 = 1 : ENDIF '2
IF PORTC PIN0 = 1 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 0 AND b2 = 0 THEN HIGH PORTC 6 : LET b2 = 1 :ENDIF '3
IF PORTC PIN0 = 0 AND PIN1 = 0 AND PIN2 = 1 AND PIN3 = 0 AND b3 = 0 THEN HIGH PORTC 7 : LET b3 = 1 :ENDIF '4
IF PORTC PIN0 = 1 AND PIN1 = 0 AND PIN2 = 1 AND PIN3 = 0 AND b4 = 0 THEN HIGH PORTB 0 : LET b4 = 1 :ENDIF '5
IF PORTC PIN0 = 0 AND PIN1 = 1 AND PIN2 = 1 AND PIN3 = 0 AND b5 = 0 THEN HIGH PORTB 1 : LET b5 = 1 :ENDIF '6
IF PORTC PIN0 = 1 AND PIN1 = 1 AND PIN2 = 1 AND PIN3 = 0 AND b6 = 0 THEN HIGH PORTB 2 : LET b6 = 1 :ENDIF '7
IF PORTC PIN0 = 0 AND PIN1 = 0 AND PIN2 = 0 AND PIN3 = 1 AND b7 = 0 THEN HIGH PORTB 3 : LET b7 = 1 :ENDIF '8
IF PORTC PIN0 = 1 AND PIN1 = 0 AND PIN2 = 0 AND PIN3 = 1 AND b8 = 0 THEN HIGH PORTB 4 : LET b8 = 1 :ENDIF '9
IF PORTC PIN0 = 0 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 1 AND b9 = 0 THEN HIGH PORTB 5 : LET b9 = 1 :ENDIF '10
IF PORTC PIN0 = 1 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 1 AND b10 = 0 THEN HIGH PORTB 6 : LET b10 = 1 :ENDIF '11
IF PORTC PIN0 = 0 AND PIN1 = 0 AND PIN2 = 1 AND PIN3 = 1 AND b11 = 0 THEN HIGH PORTB 7 : LET b11 = 1 :ENDIF '12

IF PORTC PIN0 = 1 AND PIN1 = 0 AND PIN2 = 0 AND PIN3 = 0 AND b0 = 1 THEN LOW PORTC 4 : LET b0 = 0 : ENDIF '1
IF PORTC PIN0 = 0 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 0 AND b1 = 1 THEN LOW PORTC 5 : LET b1 = 0 : ENDIF '2
IF PORTC PIN0 = 1 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 0 AND b2 = 1 THEN LOW PORTC 6 : LET b2 = 0 :ENDIF '3
IF PORTC PIN0 = 0 AND PIN1 = 0 AND PIN2 = 1 AND PIN3 = 0 AND b3 = 1 THEN LOW PORTC 7 : LET b3 = 0 :ENDIF '4
IF PORTC PIN0 = 1 AND PIN1 = 0 AND PIN2 = 1 AND PIN3 = 0 AND b4 = 1 THEN LOW PORTB 0 : LET b4 = 0 :ENDIF '5
IF PORTC PIN0 = 0 AND PIN1 = 1 AND PIN2 = 1 AND PIN3 = 0 AND b5 = 1 THEN LOW PORTB 1 : LET b5 = 0 :ENDIF '6
IF PORTC PIN0 = 1 AND PIN1 = 1 AND PIN2 = 1 AND PIN3 = 0 AND b6 = 1 THEN LOW PORTB 2 : LET b6 = 0 :ENDIF '7
IF PORTC PIN0 = 0 AND PIN1 = 0 AND PIN2 = 0 AND PIN3 = 1 AND b7 = 1 THEN LOW PORTB 3 : LET b7 = 0 :ENDIF '8
IF PORTC PIN0 = 1 AND PIN1 = 0 AND PIN2 = 0 AND PIN3 = 1 AND b8 = 1 THEN LOW PORTB 4 : LET b8 = 0 :ENDIF '9
IF PORTC PIN0 = 0 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 1 AND b9 = 1 THEN LOW PORTB 5 : LET b9 = 0 :ENDIF '10
IF PORTC PIN0 = 1 AND PIN1 = 1 AND PIN2 = 0 AND PIN3 = 1 AND b10 = 1 THEN LOW PORTB 6 : LET b10 = 0 :ENDIF '11
IF PORTC PIN0 = 0 AND PIN1 = 0 AND PIN2 = 1 AND PIN3 = 1 AND b11 = 1 THEN LOW PORTB 7 : LET b11 = 0 :ENDIF '12
GOTO TOP
This is based on the 28X/40X chip,

Here are the problems/questions.

In the simulator it shows a 28 pin chip I would prefer to have more in/outputs and use the 40 pin, do I need to issue a command at the start of the program.

As you can tell from the program I'm still learning,
If the input stays in the state for too long the output turns on and off which is no good for the project. It would be better if I could tell if the output was high already rather than using a varible.

When the simulator is running does it run at the chips processor speed?

Sorry if this is in the manual but it's very deep!

Some pointers wuld be helpful. Thanks in advance.
 

BeanieBots

Moderator
Welcome to the forum.

As you are new, I'm a little surprised to see you using the now obsolete 40X rather than the 40X1 or 40X2.

Did you know that there is a command for that. DCD & NCD?
(only on X1 and X2 parts though)

Simulator speed is a lot slower than a real chip.
You change the simulation speed. Goto "options -> Simulation" and there is a "Simulation delay (ms)" slider.

You can test the output pin status with "outpins" but again, that is not supported on the obsolete 40X.

To the best of my knowledge, the simulator will only work (visually) for 28 pin devices but the code will be OK for the 40 pin devices.
 

westaust55

Moderator
The READOUTPUTS command as described in PICAXE manual 2 page 151 will read the standard outputs on port B for all but X2 parts

Not sure what the end result is intended to be but seems excess that to test 4 portC pins you need to use 12 variables.
Would some code like this be easier and more economical on use of the limited variabes

Code:
; bits 0 to bit 3 are the lower nybble of byte variable b0
IF portC pin0 = 1 THEN
  bit0 = 1
ELSE
  bit0 = 0
ENDIF
IF portC pin1 = 1 THEN
  bit1 = 1
ELSE
  bit1 = 0
ENDIF
IF portC pin2 = 1 THEN
  bit2 = 1
ELSE
  bit2 = 0
ENDIF
IF portC pin3 = 1 THEN
  bit3 = 1
ELSE
  bit3 = 0
ENDIF
b1 = b0 AND $0F
; b1 will now have a value of 0 if no port c pin as input is high and a value from 1 to 12
; if one or more inputs is high  (and even up to 15 if all 4 inputs were high
 
Last edited:

Tasp

Member
Guys thanks so much for the replies, I've spent the last couple of days trying to work everything out.

I wasn't aware the 40X was obsolete, thanks for pointing that out.

So I would prefer to use the 40X2 as it has the maximum outputs available, so ideally 5 inputs and 28 outputs total 33 available.

Thanks for the code, however the reason for using so many variables is to keep track of whether the output is high, thus if it is high a pulse on the input will send the output low.
Is there a command for the 40X2 to test if it is already high nothing I try seems to work.
This is all the chip has to do so using all variables at an early stage shouldn't be a problem.

TIA
 

Tasp

Member
I've just found the X2 product briefing which outlines outpins(a,b,c,d) read the state of the output pins, which isn't in manual2 pdf?
 

Goeytex

Senior Member
Along these lines ....

Picaxe 28X1

I want to read the state of all the output pins (0-7) and then display the
result on the PC ( Terminal Emulator) via sertxd . But I want the display to be in binary rather than decimal.

So for example, pins 1,2, 4 & 5 are high.

Readoutpins B5 returns "54" and sertxd (#B5) sends 54 to the screen

I want to display "00110110" instead.

Is my only option to do a divide by 2 algorithm and use a variable for each
binary position ? Anyone have the code handy?
Goey
 
Last edited:

hippy

Technical Support
Staff member
The easiest way is to move the value you want to display into variable 'b0' and then display the component bits of 'b0' ...


b0 = 54
SerTxd (#bit7, #bit6, ... , #bit1, #bit0, CR, LF )

In most programs I don't use 'b0', 'b1' or 'w0' for storage variables which keeps them free for performing bit manipulation and display as and where required.
 

westaust55

Moderator
The easiest way is to move the value you want to display into variable 'b0' and then display the component bits of 'b0' ...


In most programs I don't use 'b0', 'b1' or 'w0' for storage variables which keeps them free for performing bit manipulation and display as and where required.
Concur with hippy.
For major and long/term programs, I frequently start allocating variables from the top end and keep the b0 and b1 for for bit variables as flags, etc
 

westaust55

Moderator
I wasn't aware the 40X was obsolete, thanks for pointing that out.
Obsolete means no longer manufacturer, but does not mean you cannot use one you already have if suitable for the project.

The 40X has not more IO than the 40X1 and (looking at page 8 in PICAXE manula 1) has the same hardware capabilities.
The 40X2 has no more IO just that most pins can be user defined as inputs or outputs so ore flexible.

As one moves form X thru X1 to X2, the BASIC program also gives a few more math and other functions/commands.
 

Goeytex

Senior Member
The easiest way is to move the value you want to display into variable 'b0' and then display the component bits of 'b0' ...


b0 = 54
SerTxd (#bit7, #bit6, ... , #bit1, #bit0, CR, LF )

In most programs I don't use 'b0', 'b1' or 'w0' for storage variables which keeps them free for performing bit manipulation and display as and where required.
Works Great ! Thanks
 

Tasp

Member
40X2 Chip:

Guys I'm still struggling with writing this code and in need of help.

Again the premise is that inputs A0 to A3 are read in the top loop, they are supposed to be binary inputs (a0 = 1, a1= 2, a3 = 4, a4 = 8) so a2 + a3 = 6, if output 6 is off it should turn on, if it is on it should turn off.

I'm obviously doing something very wrong, this is about the 10th time I've rewritten it trying lots of different approaches.

Thanks for any more pointers.

Code:
LOOOP:
let b0 = pinsA 'read pins (inputs A)
IF pinsA <> b0 THEN GOSUB CHK 'if inputs have changed since last time round goto check
GOTO LOOOP

CHK:
IF b0 = 1 AND pinB.0 = 0 THEN HIGH B.0 : RETURN ENDIF
IF b0 = 2 AND pinB.1 = 0 THEN HIGH B.1 : RETURN ENDIF
IF b0 = 3 AND pinB.2 = 0 THEN HIGH B.2 : RETURN ENDIF 
IF b0 = 4 AND pinB.3 = 0 THEN HIGH B.3 : RETURN ENDIF
IF b0 = 5 AND pinB.4 = 0 THEN HIGH B.4 : RETURN ENDIF
IF b0 = 6 AND pinB.5 = 0 THEN HIGH B.5 : RETURN ENDIF
IF b0 = 7 AND pinB.6 = 0 THEN HIGH B.6 : RETURN ENDIF
IF b0 = 8 AND pinB.7 = 0 THEN HIGH B.7 : RETURN ENDIF

IF b0 = 1 AND pinB.0 = 1 THEN LOW B.0 : RETURN ENDIF
IF b0 = 2 AND pinB.1 = 1 THEN LOW B.1 : RETURN ENDIF
IF b0 = 3 AND pinB.2 = 1 THEN LOW B.2 : RETURN ENDIF
IF b0 = 4 AND pinB.3 = 1 THEN LOW B.3 : RETURN ENDIF
IF b0 = 5 AND pinB.4 = 1 THEN LOW B.4 : RETURN ENDIF
IF b0 = 6 AND pinB.5 = 1 THEN LOW B.5 : RETURN ENDIF
IF b0 = 7 AND pinB.6 = 1 THEN LOW B.6 : RETURN ENDIF
IF b0 = 8 AND pinB.7 = 1 THEN LOW B.7 : RETURN ENDIF
Also the loop seems to miss inputs sometimes, so I'm sure theres a better way of testing for changes to inputs?
 

BeanieBots

Moderator
It's not clear (to me) exactly what you want to acheive.
Please explain in simple terms what you to happen. Maybe give a few exact amples of what a particular input pattern should produce on the outputs.
 

Svejk

Senior Member
Code:
let b0 = pinsA 'read pins (inputs A)
IF pinsA <> b0 THEN GOSUB CHK 'if inputs have changed since last time round goto check
The test result if pinsA <> b0 will be allways false and your loop will go forerever.

You should test first for change and then assign to b0 the value of PinsA. Your loop should look like this.

Code:
Main:
  if pinsA <> b0 then gosub chk     'test for change
  let b0 = pinsA                        'assign current status to b0
  pause 10                               
goto main
 
Last edited:

hippy

Technical Support
Staff member
The concept is to use the PIC as a 3 to 8 decoder ie. (74HS138) however I need the PIC to latch until the input pulses again,
So 1st pulse turn output on, 2nd pulse turn output off, simple!
(inputs 0 to 3 are binary so a combination activates the relevant output)
Again the premise is that inputs A0 to A3 are read in the top loop, they are supposed to be binary inputs (a0 = 1, a1= 2, a3 = 4, a4 = 8) so a2 + a3 = 6, if output 6 is off it should turn on, if it is on it should turn off.
I think you need to clarify exactly what you want as the two specifications do not tally. I cannot understand why there are four inputs for what amounts to a 3-to-8 decoder, not sure under what conditions you want an output to toggle. You refer to input A0 to A3 then use a0, a1, a3 and a4.

What you want may be quite simple but it's hard to understand exactly what you do want. The following may be close, using A.0, A.1 and A.2 as the bit number, A.3 as a trigger to change output bit ....

#Picaxe 40X2

Symbol bitNumber = b0
Symbol outputBits = b1

dirsB = %11111111
Do
Do : Loop Until pinA.3 = 0
Do : Loop Until pinA.3 = 1
bitNumber = pinsA & %00000111
outputBits = 1 << bitNumber ^ outputBits
pinsB = outputBits
Loop


In simulation ...

1) Set the bit number on A.0, A.1 and A.2, then set A.3 and the appropriate bit will be set on output port B, clear A.3.

2) Set A.3 again and the bit will be cleared, again clear A.3.

3) Set a different bit number on A.0, A.1 and A.2, set A.3 and that bit will toggle on, clear A.3.

4) Repeat (3) indefintely.
 

Tasp

Member
Ok, thanks for the replies and for the code, and sorry for confusing everyone, the a0, a1, a3, a4 is a typo it should be a0, a1, a2, a3, a5 (a4 is output only on the chip) for "binary" type inputs;
ie. a0 = 1, a1 = 2, a2 = 4, a3 = 8, a5 = 16,
These inputs refer to 1 of 24 outputs starting at B0 which is 1, B1 = 2, B2 = 3......D4 21....etc so if,

a0 (high) + a2 (high) = 5 (refers to output B5).
a2 (high) + a3 (high) = 12 (refers to output C3).
a2 (high) + a5 (high) = 20 (refers to output D3).

The 3 to 8 decoder was the original type of concept that evolved as more outputs were available with the 40X2. As well as a way of helping to explain (poorly!) what I'm trying to achieve.
Except unlike a 3 to 8 decoder on the first input the output should turn on and the second input it should turn off, so,

a0 (high) + a2 (high) = 5 (refers to output B5). Output B5 turns on.
a2 (high) + a3 (high) = 12 (refers to output C3). Output C3 turns on.
....other inputs and outputs occurring......
a2 (high) + a3 (high) = 12 (refers to output C3). Output C3 turns off.
a2 (high) + a5 (high) = 20 (refers to output D3). Output D3 turns on.
a0 (high) + a2 (high) = 5 (refers to output B5). Output B5 turns off.

It is supposed to check the inputs on a0 to a5 (except a4 as it's output only) constantly and check for changes, because I only have the ability of 4 inputs into the Pic from the trigger device.

Does this help explain any better what I'm trying to do?
 
Last edited:

westaust55

Moderator
Does this get close to what you are trying to do:

Code:
Entry:
b0 = 0
IF A.0 = 1 THEN
  bit0 = 1
ENDIF
IF A.1 = 1 THEN
  bit1 = 1
ENDIF
IF A.2 = 1 THEN
  bit2 =1
ENDIF
IF A.3 = 1 THEN
  bit3 =1
ENDIF
IF A.5 = 1 THEN
  bit4 =1
ENDIF

;now b0 has a value equal to the binary value present on the input pins of portA
; where A.5 represents bit 4
if b0 = b2 THEN GOTO Entry ; return as there is no change

b2 = b0  ; save b0 in b2 for the check for input state change on the next cycle

IF b0 = 1 THEN
  TOGGLE B.0
ENDIF
IF b0 = 2 THEN
  TOGGLE B1
ENDIF
IF b0 = 3 THEN 
  TOGGLE B.2 
ENDIF 
IF b0 = 4  THEN 
  TOGGLE B.3 
ENDIF
IF b0 = 5 THEN
  TOGGLE B.4
ENDIF
IF b0 = 6 THEN
  TOGGLE B.5
ENDIF
IF b0 = 7 THEN
  TOGGLE B.6
ENDIF
IF b0 = 8 THEN
  TOGGLE B.7
ENDIF
GOTO Entry

The problem here is that say you have inputs 0 and 2 high for the value 5 and wish to change to the value 6 needing inputs 1 and 2 high

then as an intermediate step you must either have input 0 low giving a value 4 in b0 or you must have input 1 high giving an intermediate value of 7

The code is not checking for these intermedate states which will give false output operations.

Thus, you will need some better means of identifying when a desired new input state has really been achieved.
 

Tasp

Member
Erm, it looks good but won't run for me, says syntax error on IF A.0 = 1 THEN ???

I'm hoping the inputs will be able to change altogther thus not proving a problem.
 

westaust55

Moderator
Sorry,

(not actaully an X2 user myself as yet)

From a quick check in manual 2, that should be in the format:

IF pinA.0 = 1 THEN
 

Tasp

Member
Thanks Westaust55 (and of course to everyone) this seems to be what I was trying to do, I added a brief pause just under Entry: to allow for input changes, but until I get this ported on to a chip and the reset of the circuitry done I won't know. But you could well be right the potential problems of the intermediate states.
 
Top