View previous topic :: View next topic |
Author |
Message |
TSEYFARTH
Joined: 01 Jul 2006 Posts: 1054
|
Posted: Sun Jul 03, 2011 2:23 am Post subject: Cannot read status of output pin |
|
|
Hello,
I am trying to read the status of aliased output pins. Each time I get a compiler error for invalid data type. Can anyone tell me where I am going wrong?
Code: |
Relay1 Alias Portd.3
Config Relay1 = Output
Relay1 = 0 'set low
For Y = 0 To 7
If Relaystatus.y <> Relay1 Then Snddata = 1
next Y
|
Thanks
Tim |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Sun Jul 03, 2011 3:47 am Post subject: |
|
|
You might need to read the port into a temporary variable, then do the compare.
Code: |
Dim bTemp as byte
bTemp = relay1 'assign port to variable
|
Then use bTemp in the If statement.
But since you already know the status of the relay - you set it somewhere ! I dont see much point in reading it. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
TSEYFARTH
Joined: 01 Jul 2006 Posts: 1054
|
Posted: Sun Jul 03, 2011 4:16 am Post subject: |
|
|
Hi Adrian,
Nice to hear from you!
I had tried that before with code like this:
Code: |
For Y = 0 To 7
Tempb = Relay1
If Relaystatus.y <> Tempb Then Snddata = 1
|
RelayStatus is a byte variable.
[/code]
For Y = 0 To 7
Tempb = Relay1
R = Relaystatus.y
If R <> Tempb Then Snddata = 1
[code]
The compiler dies on the if line in both cases.
Any other ideas?
Here is the compiler info:
Compiler version :2.0.6.2
Compiler build :2.0.6.2.002
IDE version :2.0.6.2
Windows OS :Windows 7 Home Premium
Windows SP :
Explorer :8.0.7600.16385
Company :Microsoft
Owner :Microsoft
Windows dir :C:\windows
App data dir :C:\Users\Notebook\AppData\Roaming
System dir :C:\windows\system32
Chip and Stack info:
$regfile = "m88def.dat" 'register file for MEGA16-16AC
$crystal = 16000000 '16MHz crystal
$baud = 9600
$hwstack = 150 '128 '80 '64 ' default use 32 for the hardware stack
$swstack = 150 '128 '32 '16 ' default use 10 for the SW stack
$framesize = 128 '96 '64 '40 ' default use 40 for the frame space
Thanks again!
Tim |
|
Back to top |
|
|
TSEYFARTH
Joined: 01 Jul 2006 Posts: 1054
|
Posted: Sun Jul 03, 2011 4:28 am Post subject: |
|
|
Sorry - found. I had the var Senddata spelled wrong.
Too many hours working - sorry for the bother, and thank you for the help!
Tim |
|
Back to top |
|
|
TSEYFARTH
Joined: 01 Jul 2006 Posts: 1054
|
Posted: Sun Jul 03, 2011 4:41 am Post subject: |
|
|
Well, I guess I found it too soon. There is still a problem, same as before:
Code: |
For Y = 0 To 7
If Y = 0 Then Tempb = Relay1
If Y = 1 Then Tempb = Relay2
If Y = 2 Then Tempb = Relay3
If Y = 3 Then Tempb = Relay4
If Y = 4 Then Tempb = Relay5
If Y = 5 Then Tempb = Relay6
If Y = 6 Then Tempb = Relay7
If Y = 7 Then Tempb = Relay8
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
If Relaystatus.y <> Tempb Then Senddata = 1
Next Y
|
I get an error 31 on the line "If Relaystatus.y <> Tempb Then Senddata = 1" and also an error 124 (loop expected). If I remark this for next loop, the error goes away!
Tim |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Sun Jul 03, 2011 6:02 am Post subject: |
|
|
I dont see the reason for that error, but what you do seems unnecessarily long-winded. Assuming all the relays are on one port, why not just do something like:
Code: |
bTemp = RelayPort 'read the port to get the status
bChange = bTemp xor relaystatus 'xor will return any changed bits as ones ( set )
if bChange > 0 then 'at least 1 relay changed state
'test each bit in here
'based on your example, it would be enough to do
SendData = 1 'set the flag if any relay has changed state
end if
|
Then just go through each bit in bChange to see which ones are set, after testing it first for zero ( no change ).
I still see no reason to do all that testing anyway - your program must have set the states, so it 'knows' what the state is, why test for it ? _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
TSEYFARTH
Joined: 01 Jul 2006 Posts: 1054
|
Posted: Sun Jul 03, 2011 6:09 am Post subject: |
|
|
Hi Adrian,
Thank you for your reply!
The relays are on 2 ports, B and D.
The program does set the port, but for some reason, they are always reporting a zero, even though I know the relay is closed. The uC drives a 2N2222 which in turn drives the relay coil.
The only reason TO do this, was to test the current state of the relays and report if changed. There are >1 print routines, but it seems that those are working properly. The only other cause I could see is if an interrupt changed the flag for the print setting (0,1,2).
Still very strange why it does not compile. Any reported bugs with this newer version of BASCOM?
Tim |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Sun Jul 03, 2011 8:00 am Post subject: |
|
|
Hi,
If port is made output, then reading PINx register will
give you data that has been output on port pins.
Best regards,
Luciano |
|
Back to top |
|
|
TSEYFARTH
Joined: 01 Jul 2006 Posts: 1054
|
Posted: Sun Jul 03, 2011 8:07 am Post subject: |
|
|
Hello Luciano!
This is what I want, to know the state of the output ports.
Tim |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Sun Jul 03, 2011 8:37 am Post subject: |
|
|
Hi,
If port is made output, then reading PINx register will
give you data that has been output on port pins.
* * *
PinD not PortD to read the logic level present on the pin!
Code: | $regfile = "m88def.dat"
$crystal = 4000000
Config Pind.3 = Output
Portd.3 = 1
Print Pind.3
Portd.3 = 0
Print Pind.3
End |
The above code works in a real AVR chip but not in the Bascom simulator.
Tested with:
Compiler version :2.0.6.2
Compiler build :2.0.6.2.002
IDE version :2.0.6.2
Best regards,
Luciano
Last edited by Luciano on Sun Jul 03, 2011 8:45 am; edited 2 times in total |
|
Back to top |
|
|
xury
Joined: 28 Jun 2011 Posts: 10
|
Posted: Sun Jul 03, 2011 8:38 am Post subject: |
|
|
Hello TSEYFARTH
Your problem stems from the fact that you are trying to read from the register of the port, not a pin.
This is a part of your code:
Code: | Relay1 Alias Portd.3
If Relaystatus.y <> Relay1 Then Snddata = 1 |
You should create new alias to the pin register:
Pin_relay1 alias Pind.3
and compare to this.
To reading always you have to use pin register, to setting use port register. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Sun Jul 03, 2011 10:12 am Post subject: |
|
|
what is this : Relaystatus ?
is this a variable or an alias of what?
this works for me :
dim Relaystatus as byte,y as byte
Relay1 Alias Portd.3
If Relaystatus.y <> Relay1 Then
nop
else
nop
endif
When a port/pin is used in output mode, reading the port status, returns the value you had set it too.
unless i missed something in the datasheet, it is not needed to read from the PIN register. In fact it could return the wrong value when there is a big load.
When pin is used in input mode, you must use the PIN register.
This is something from an old atmel databook (could not find it in the pdf) : when reading PORTB, the PORTB data latch is read, and when reading PINB the logical values present on the pins are read.
So IMO you should read the PORT register to learn how the output is set. Not taking into account the load on the pin.
I have no time to test it but it would be interesting. _________________ Mark |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Sun Jul 03, 2011 11:30 am Post subject: |
|
|
albertsm wrote: | it is not needed to read from the PIN register.
In fact it could return the wrong value when there is a big load. |
Hi Mark,
Yes, you can just read the data register of the port, but if you want to verify
the logic level effectively present on the output pin you can do that by reading
its "input".
(Example).
Initial situation: The pin is configured as output and the pin is set to low.
When you write a "1" to the data register of the above pin, the pin is driven
from GND to VCC and the speed of this transition depends on the type of load
connected to the pin. If you need to verify that the pin has reached the logic
level "1" then you can do that by reading its input. (This will also tell you if the
output buffer of the pin is still working ok).
Best regards,
Luciano |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Sun Jul 03, 2011 12:15 pm Post subject: |
|
|
but what do you read via the PIN register if you write a '1' and there is a big load ?
you will read a 0 while the actual latch state is '1'.
only if you buffer the output it is safe to read the PIN.
The above problem was from a customer problem long time ago. I see in the PDF that ports have changed : they can sink and source current and maybe it does not give the original problem.
Still i would test the PORT instead of the PIN. _________________ Mark |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Sun Jul 03, 2011 1:46 pm Post subject: |
|
|
albertsm wrote: | but what do you read via the PIN register if you write a '1' and there is a big load ?
you will read a 0 while the actual latch state is '1'. |
Yes, with an inductive load for example, you will read first a "0" but by reading the pin many times
in a loop, you can make your software wait until a "1" is effectively present on the pin. All depends
on the application. This will also tell you if the output buffer of the pin is still working ok.
Best regards,
Luciano |
|
Back to top |
|
|
|