PDA

View Full Version : 12f675_fuse_about_to_blow!



Pages : 1 2 3 [4]

mackrackit
- 6th September 2010, 12:58
Have you tried setting the port parameters in device manager? Maybe VB relies on those settings?

LEDave
- 6th September 2010, 15:53
Have you tried setting the port parameters in device manager?

A good idea that mackrackit, the baud rate was set differently but when adjusted still the same sort of input.

I think my program needs adjusting / more work, Ill have another look tonight.

Dave

LEDave
- 7th September 2010, 23:22
Hi mackrackit,

Another small step forward tonight in that I changed the line in the PIC code from:


SEROUT2 PORTC.3, 16780, [DEC z, 10, 13]

To this:


SEROUT2 PORTC.3, 16780, [DEC z]

Removing the line space? and carriage return made the VB program display a continual vertical line of numbers (no more gibberish:) )

All I need to do now is to make the VB read each individual BYTE in the COM PORT instead of a continual line of numbers (BYTES).

Dave

mackrackit
- 7th September 2010, 23:56
Interesting..
What if you try
,$d,$a
in place of
,10,13

Maybe that would make VB happy?

LEDave
- 8th September 2010, 00:34
Well, what happens now is, the data is coming in (vertical line of numbers on the left hand side of the listbox) so I'm getting for example:

1
3
5
*
*
2
0
3
*
*
1
1
*
*
The asterisk's represent what appears to be a number 1 in a thin bold square, which occurs after each transmitted BYTE with a four second delay as per the program, interesting. The Serial Communicator still worked a treat with ,$d,$a. I need to get the incoming numbers Horizontal and maybe spaced one line apart for ease of reading.

Any other ideas?

Dave

mackrackit
- 8th September 2010, 01:05
I think I may be confused.
VB has the numbers
1
3
5
*
*
2
0
3
*
And Serial Communicator has them
135
203
??

LEDave
- 8th September 2010, 05:20
That's spot on mackrackit.

I think the VB prog maybe displaying the correct random BYTE sent from the PIC only vertically as opposed to horizontally.

Dave

mackrackit
- 8th September 2010, 09:04
Are you DIMing the VB input as a string as shown here. "Dim recepcao As String"
http://www.picbasic.co.uk/forum/showthread.php?t=13609&p=92628#post92628

LEDave
- 8th September 2010, 23:35
Hi mackrackit,

Sorry for the late reply.


Are you DIMing the VB input as a string as shown here. "Dim recepcao As String"

Well I tried to. The problem is with the posted program as I see it, is that it's not actually outputting any data to a Textbox or Listbox which is what I need to do .Also with VB 2008 you have to use INVOKE or an INVOKER to make a cross thread call else you incur an error(I think).

Here are my two programs. One from the other thread below (Which doesn't receive data):


Public Class Form1
Dim WithEvents SerialPort1 As New IO.Ports.SerialPort
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

SerialPort1.PortName = "COM1"
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.BaudRate = 2400
SerialPort1.DataBits = 8
SerialPort1.StopBits = 1
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If SerialPort1.IsOpen = False Then SerialPort1.Open()
If SerialPort1.IsOpen = True Then MsgBox("com1 port opened sucessfully")
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If SerialPort1.IsOpen = True Then SerialPort1.Close()
If SerialPort1.IsOpen = False Then MsgBox("com1 port closed sucessfully")

End Sub

Private Sub DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim recepcao As String

recepcao = SerialPort1.ReadExisting



End Sub


Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
SerialPort1.Write(ListBox1.Text)


The other using INVOKE which nearly works, it stacks the incoming data vertically (as previously discussed) but it does receive data from the PIC:


Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.Windows.Forms


Public Class Form1


'Buffer for receievd data***

Private Delegate Sub AddListBoxItemInvoker(ByVal item As Object)


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.PortName = "COM1"
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.BaudRate = 2400
SerialPort1.DataBits = 8
SerialPort1.StopBits = 1

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

If SerialPort1.IsOpen = False Then SerialPort1.Open()
If SerialPort1.IsOpen = True Then MsgBox("com1 port opened sucessfully")

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If SerialPort1.IsOpen = True Then SerialPort1.Close()

If SerialPort1.IsOpen = False Then MsgBox("com1 port closed sucessfully")

End Sub



Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

Me.AddListBoxItem(SerialPort1.ReadExisting)


End Sub

Private Sub AddListBoxItem(ByVal item As Object)

If Me.ListBox1.InvokeRequired Then
'We are on a secondary thread so delegation is required.
Me.ListBox1.Invoke(New AddListBoxItemInvoker(AddressOf AddListBoxItem), (item))

Else
'We are on the primary thread so add the item.
Me.ListBox1.Items.Add(item)
End If
End Sub
End Class

Any ideas? Or maybe a passing VB'er might have the answer.

Should I post this over on the other thread do you think?


Dave

mackrackit
- 9th September 2010, 00:06
Should I post this over on the other thread do you think?
yup
I would. Makes no sense to me.

LEDave
- 9th September 2010, 00:30
Hi mackrackit,

I've posted it over on the VB thread (link below). Will be interesting to see if anyone has any ideas.

http://www.picbasic.co.uk/forum/showthread.php?t=13609&p=93607#post93607

Dave

LEDave
- 9th September 2010, 09:22
Hi mackrackit,

Henrik looks like he's cracked the problem over on the VB thread.

I'll work on it tonight.

Dave

mackrackit
- 9th September 2010, 11:13
I saw that.
Seems obvious now.

LEDave
- 9th September 2010, 22:58
Hi mackrackit,


Seems obvious now.

That's because your'e clever. Hopefully I'll say that one day.

I've just posted a reply to Henrik on the VB thread (link below).

In a nutshell, the VB program is reading and displaying Random Bytes a treat now:) Apparently though birds fly in and out of nest boxes a lot more the 255 times a day when they're feeding young (It'll be interesting to see just how many) so a Word is needed as a counter, so half way there now then.

http://www.picbasic.co.uk/forum/showthread.php?t=13609&p=93663#post93663

Dave

mackrackit
- 10th September 2010, 10:56
I have been called many things, clever has not been one of them :)

Birds..
WORD size , I would think will be large enough for a day? Week? Sooner or later that will not be large enough.

So when counting you can go very large even using BYTE size. Have the count be a power of 100.

A simple example.
Count to 100 with VAR1. When 100 is reached VAR2 increments and VAR1 starts over.
VAR2 will have 100s and VAR1 will have ones and tens.

But get the WORD thing working :)

LEDave
- 10th September 2010, 11:24
Count to 100 with VAR1. When 100 is reached VAR2 increments and VAR1 starts over.
VAR2 will have 100s and VAR1 will have ones and tens.

See what I mean, very clever:)


But get the WORD thing working

I'll be on it tonight:) And probably tomorrow night too. :eek:

Dave

LEDave
- 10th September 2010, 23:49
But get the WORD thing working

I think it is:)

Have a look at the screen-shot on the other thread, what do you think?

http://www.picbasic.co.uk/forum/showthread.php?t=13609&p=93747#post93747

Dave

mackrackit
- 11th September 2010, 03:40
looks good!!!

You are doing a fine job :)

And yes, I am following the other thread..

LEDave
- 11th September 2010, 12:43
You are doing a fine job

Cheers mackrackit, I wouldn't be without your and Henriks help though.

Yes the bare bones are taking shape with the Form, a lot of tweaks could be made though (having the COM Port open / shut automatically, clearing the buffer etc).

Next job to get the PIC to send High then Low Bytes and have VB join them back into a Word.

Fascinating stuff this.

Dave

LEDave
- 14th September 2010, 16:31
Hi mackrackit,

Should I carry on tweaking the VB Terminal program for now or look at the rfPIC-TxRx program?

It's amazing how even learning how to make what appears to be the simplest of changes can take a whole evening. Sometimes I don't even know the term for what it is I'm trying to achieve / change...doh.

Dave

mackrackit
- 14th September 2010, 16:44
Looks like you have VB under control for what you want to do to start with.
Might as well work on the RF some.

I know what you mean about terms and things. One of the problems with being self taught I guess.

LEDave
- 14th September 2010, 23:01
Looks like you have VB under control for what you want to do to start with.

Yes, having a VB Terminal program via a usb / db9 cable that magically receives Random numbers from the PIC to pc is a result alright:)

I've managed to get a txt file to open with a button click to write the Bird count Bytes to.

Seriously interesting stuff this.

Dave

LEDave
- 29th September 2010, 23:10
Hi mackrackit,

I haven't left the Country. I've had a few things to deal with of late but still learning in between times.

Dave

mackrackit
- 30th September 2010, 00:04
I figured as much.
Are you working on RF or VB lately?

LEDave
- 30th September 2010, 14:11
Are you working on RF or VB lately?

I've spent some time looking at Bruce's rx / tx program to try and figure out 1/ exactly how it works and 2/ To modify it to transmit (and then receive) firstly a byte, then a word to send to the Terminal program.

On the VB front, I'm looking to make the VB Terminal program read the transmitted data from the PIC and auto-write that information to a txt file.

I guess I'm riding two horses (and juggling three balls in my private life right now). I guess I should focus on one (the VB or the rx/tx that is).

Dave

LEDave
- 9th October 2010, 00:04
Hi mackrackit,

Are these 'private messages' you can send on this Forum private / ish.

Dave

mackrackit
- 9th October 2010, 00:07
Yes, they are private.

LEDave
- 2nd November 2010, 21:04
Hi everyone,

I've just managed to get the rfPIC TX/RX to work and blink the two led's on the PICkit1. It took me over an hour to figure out and find which program and where the program was on my hdd (must improve my house keeping). I still find it amazing that it's radio waves travelling through the air that makes all this work.

Ok, so the program's I used were the microchip rx/tx.hex demo program's written in assemly language. However, for the project I need to compile Bruce's TX / RX program's which are written in PB with a little assembler in the mix and compile them using the MPLAB compiler (have I got that right?) then modify the code for the project.

So step one, I need to go away and learn how to compile a program and create a hex file using MPLAB (something I've never done before) I'm pretty sure I've a tutorial somewhere.

Just a little refresher, am I right in thinking that PBP compiles PIC Basic and MPLAB compiles everything, well PIC Basic and Assembly?

Good to be back.

Dave

mackrackit
- 2nd November 2010, 21:46
You do not have to use MPLAB. MPLAB is just an editor, basically.
But you do or should be using MPASM.
To do this with Micro Code Studio go to Tools- Compiler Options then the assembler tab. Check MPASM.

Good to have you back.

LEDave
- 2nd November 2010, 22:33
Good to have you back.

Cheers mackrackit:)


To do this with Micro Code Studio go to Tools- Compiler Options then the assembler tab. Check MPASM.

Well I can't actually see 'Tools' on the toolbar, here are three screen shots which I think show my current setup:

LEDave
- 2nd November 2010, 22:46
I thought I'd add a screenshot of the 'toolbar' so you can see what I've got highlighted and what's greyed out under current settings. Does this look ok to you?

ScaleRobotics
- 3rd November 2010, 00:44
That looks about right for that chip. You should have save available though! Maybe you need to have some code in the window for that. Looks like most of the greyed out options are for the in circuit debuger. Some other chips: 16F627(A), 16F628(A), 16F73, 16F74, 16F76, 16F77, 16F870, 16F871, 16F873(A), 16F874(A), 16F876(A), 16F877(A), 16F87, 16F88, 18F242, 18F248, 18F252, 18F258, 18F442, 18F448, 18F452, 18F458, 18F1220, 18F1320, 18F2220, 18F2320, 18F4220, 18F4320, 18F6620 and 18F8620

have an in circuit debug available for them, but as you can see, they are a bit limited. It is an interesting feature though.

Walter

4906

LEDave
- 3rd November 2010, 01:44
Hi Walter


You should have save available though! Maybe you need to have some code in the window for that.

Exactly that, I added some code and 'Save' changed from greyed out to Bold.

That was interesting, I changed the chip from a 12F675 to a 16F627(A) and the RUN-STOP-STEP-PAUSE changed from greyed out to Bold,
like you said then that must be because the chip has a Debug available to them (I've never used Debug).

Cheers: Dave

ScaleRobotics
- 3rd November 2010, 02:07
(I've never used Debug).


Hi Dave,

Bruce did a great write up on how to use it here: http://www.rentron.com/PicBasic/MCS_X3.htm

I used to use it, and it is pretty cool. When I needed to try to debug things that were using the serial port already, I had to find other ways to debug (not necessarily better). But I would say it can be pretty helpful when you are starting out.

The way it debugs is that it adds code into your program to talk back and forth through the serial port. That way it updates registers, etc so you can see them in the ICD. It uses a fair amount of resources, so it slows things down a great deal, but it is fast enough for a lot of projects.

LEDave
- 3rd November 2010, 10:30
Thanks for that Walter and the link, very interesting and something else to look into.

Dave

LEDave
- 3rd November 2010, 23:34
We've touched on this before, when I compile Bruce's TX program I get these errors (see attachment). This is because as mackrackit said earlier in the thread:


Bruce is using PM for an assembler in that example.

And:


PM is the assembler from the Pic Basic folks. It works well on the older and smaller chips.

Also:


MPASM from MicroChip works for everything.

So the compiler error is due (I think) to having the wrong type of configuration fuse in Bruce's program (see second attachment) and I need to change them to this type (see third attachment) and it will compile.

Have I got that right?

Dave

mackrackit
- 4th November 2010, 11:31
You will want to change these lines in your code

@ DEVICE PIC12F675,MCLR_OFF,INTRC_OSC_NOCLKOUT,WDT_OFF,BOD_ OFF
@ DEVICE PWRT_ON,PROTECT_OFF
to

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
when using MPASM as an assembler.

And comment the *.inc file in the PBP directory.

http://www.picbasic.co.uk/forum/content.php?r=157-Presetting-Configuration-Fuses-(PIC-Defines)-into-your-Program

LEDave
- 5th November 2010, 02:49
Hi mackrackit,

Well I changed the lines of code and compiled the program without commenting the the *.inc file in the PBP directory and the compiler gave the error below(see attachment). I was expecting that as per your Forum link.

It's the
comment the *.inc file in the PBP directory. that's causing me the problem and I've conFUSED myself big time here. The only .INC files I can find are in this path:C:\Program Files\Microchip\MPASM Suite. I've read the Forum page link you posted up but I still can't see what I need to do.

Another pointer if poss please.

LedimDave

mackrackit
- 5th November 2010, 03:15
C:\PBP
That is where the inc's are. If things are installed in the default location.
The ones in the MPASM directory do not modify.

LEDave
- 5th November 2010, 23:41
Can't believe I couldn't find the PBP.INC files talk about under my nose:eek:

Anyway moving on, I've found the 12F675.INC (PBP) file and think I've 'commented out' the right line (see attachment) which probably means I haven't:( Is what I've done what I'm meant to do?)


;device pic12F675, intrc_osc_noclkout, wdt_on, mclr_on, protect_off

Dave

mackrackit
- 6th November 2010, 00:29
Yes, that is the correct line to comment when setting the fuses PM style in code space. Comment the line starting "__ config" when using MPASM style.
Both can be commented at the same time.

LEDave
- 6th November 2010, 00:48
Hi mackrackit,


Both can be commented at the same time.

I did both and the TX program compiled with no errors:) In the morning I'll change the RX fuses and then it's onto the programs themselves to send and receive the bird_box_count_data, exciting stuff.

Dave

LEDave
- 6th November 2010, 22:19
I've had a good night tonight. I've managed to get Bruce's RX program which uses a PIC12F676 (which I don't have) to work on a 16F684 which I do, so well pleased.

Dave

mackrackit
- 7th November 2010, 00:08
WOOHOO!!!
Now you getting it. Good job!!!

LEDave
- 7th November 2010, 00:40
WOOHOO!!!:D


Now you getting it.

Well another step forward for sure:)


Good job!!!

Cheers mackrackit.

Dave

LEDave
- 7th November 2010, 22:21
In Bruce's TX program under the section of Constants, he has PreAmble CON with a value of 15 HEX (I'm happy with that) Then he has Synch CON "~" = 7E HEX(I think) but how does "~" = anything if you see what I mean?


' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte

Dave

LEDave
- 7th November 2010, 23:13
In Bruce's TX program under the section of Constants, he has PreAmble CON with a value of 15 HEX (I'm happy with that) Then he has Synch CON "~" = 7E HEX(I think) but how does "~" = anything?


' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte

*** Ah, I just figured it out 7E HEX is the ASCII value for the ~ symbol right?***

So sending and receiving that symbol acts as a Synch BYTE is that right?

Plus sorry I seem to have posted twice instead of editing.

Dave

mackrackit
- 7th November 2010, 23:36
""So sending and receiving that symbol acts as a Synch BYTE is that right?""
Yup.

LEDave
- 7th November 2010, 23:47
Cheers mackrackit.

It's a funny game this programming, I've been scratching my head for ages trying to figure out how the Synch BYTE worked, then when the penny dropped it all seemed fairly obvious (it didn't until the penny dropped though). Still, another piece fits into the learning jigsaw I guess.

Dave

LEDave
- 8th November 2010, 21:47
I've been doing lots of reading and slowly trying to work my way through the TX / RX progs to get an understanding of what's actually happening, the sequence etc. One thing I can't see though is this.

In the TX program we've got:


SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM]

And the RX has:


SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM]

So my Q is this: What's happened to the 'PreAmble BYTE' ?


PreAmble CON $A5 ' 10100101 preamble

The Manual says:


The list of data items to be received may be preceded by one or more qualifiers between parenthesis after WAIT. SERIN2 must receive these bytes in exact order before receiving the data items. If any byte received does not match the next byte in the qualifier sequence, the qualification process starts over

So in this case that would be the Synch BYTE right? Synch BYTE always first (because of the WAIT command), the rest to follow. I can't see where / how the preAmble arrives though.

Also this from WIKI:

http://en.wikipedia.org/wiki/Syncword

Suggest to me that a PreAmble and a Synch are two ways of doing the say thing, or very similar, have a got that on right?

Dave

mackrackit
- 9th November 2010, 00:26
The short answer about the pre-amble is it sets up the receiver hardware with data that is not noise so when the remainder of the data comes in, in our case the SYNCH, the SYNCH byte is easily detected from noise.... The receiver hardware acts on it but not the receiver code.
SYNCH is for software
PRE-AMBLE is for hardware
Something like that.

The long answer.
http://davehouston.net/RFTipsTricks.htm

LEDave
- 9th November 2010, 00:54
Hi mackrackit, thanks for the reply.

I'll settle for the short answer right now (I'm off to bed in a mo) and read the long answer tomorrow.

Dave

LEDave
- 13th November 2010, 22:02
Bruce's program is very well documented, it would be good to know I'm reading how to put the PIC to sleep and wake on interrupt. Am I on the right lines here?


INTCON = %00001000 ' Enable port change wakeup from sleep

Setting INTCON REG bit 3 to 1 enables the GPIO port change interrupt, the interupt flag is set on INTCON REG bit 0. (I'm thinking bit.0 is now logic 1 until cleared.)


IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4

Setting the IOC pins 3 / 4 (button presses) to logic 1 (goes low when button pressed).


Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.
IF (GPIO.3=1) AND (GPIO.4=1) THEN ' pins will be 0 only when buttons are pressed
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No buttons down, so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz
@ NOP ' Do nothing for 1st instruction on wake-up
ENDIF
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

So if no button is pressed:
1/ GPIO.3 / 4 stay high
2/ E_OUT=0 the transmitter (SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output) stays off.
3/ INTCON.0 = 1 changes to INTCON.0 = 0 (software reset)
4/ @ SLEEP (The PIC goes to sleep, no time value set).
5/ @ NOP (I'll take as per NOP above, I couldn't find anything on this in the manual).

If buttons on GPIO.3/4 are pressed then the program continues....... As I will tomorrow.

How does this look?

Dave

mackrackit
- 14th November 2010, 04:54
3/ INTCON.0 = 1 changes to INTCON.0 = 0 (software reset)
INTCON.0 will only "=1" when one of the IOC pins change state. The code makes sure the "trigger" is set before sleeping. I think you got that though.


5/ @ NOP (I'll take as per NOP above, I couldn't find anything on this in the manual).
No Operation... I am here but I ain't doing nothing.
Look to the data sheet under Instruction Set Summary. The ASM instructions are found there.

Looks like you have been studying :)

LEDave
- 14th November 2010, 16:11
Cheers mackrackit, I was pretty close then-ish.:)

I think I've got the whole sequence now:

INTCON REG bit 3 set to 1 enables the INTCON REG flag bit 0. Bit 0 changes 'flags' when a button is pressed which is controlled by ( IOC = %00011000 - the buttons in effect)

It was this line from the program that threw me:


INTCON.0 = 0 ' No buttons down, so clear int on change flag

I originally thought that if no buttons were down then INTCON.0 = 0 so there was no flag to clear but on reading Bruce's:
' No buttons down, so clear int on change flag made me think it must be set to '1'.

Thanks for the explanation.

Dave

mackrackit
- 14th November 2010, 16:22
Sometimes it is hard to say. From the data sheet.

bit 0 GPIF: Port Change Interrupt Flag bit
1 = When at least one of the GP5:GP0 pins changed state (must be cleared in software)
0 = None of the GP5:GP0 pins have changed state
If one of the two buttons were down and the other up when the bit was cleared,( made zero), then releasing one OR pushing the other will cause the flag to be set, (bit 0 = 1) , just looking for a change, any change.

LEDave
- 14th November 2010, 17:11
Thanks for that mackrackit, I think I'm there now:)

Just as an aside here, when I first started PIC programming in February I think it was, I never thought I'd ever figure out how any of the registers worked. I think I'm slowly getting there now though.:D

So the last bit of program from the Main: section was:


ENDIF
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

Which is GPIO.5 RF transmitter enable output (SYMBOL E_OUT = GPIO.5).

So the next part is the Encoding. I've got an idea on how this works (but not the full picture), I'll post up later.

Dave

LEDave
- 14th November 2010, 21:45
I've just spent two hours working on a post which I'm not going to post for the minute.

However Question:

How does:
DAT_OUT.0[1] work? Or were do I look for the solution, is it in the manual? (I'd rather try and find the answer) if I can't I'll ask;)

The whole piece of code is:
DAT_OUT.0[1]=~GPIO.3 I think the
~GPIO.3 part simply sends to GPIO.3

From the manual:


If you don't want MicroCode Studio to interpret a control sequence, but rather send it as normal characters, then just use the tilda symbol (~) in front of the $ or # symbol. For example, letter ~#9712345 would be sent as letter #9712345.

Have I got that bit right?

Dave

mackrackit
- 14th November 2010, 22:04
(I'd rather try and find the answer) if I can't I'll ask
:D COOL!!!

"~" Look at the table under Math Operators 4.17 in the PBP manual.

And these may help.
http://www.picbasic.co.uk/forum/showthread.php?t=544
http://www.picbasic.co.uk/forum/showthread.php?t=13529&p=91955#post91955
http://www.picbasic.co.uk/forum/showthread.php?t=66&p=189#post189

You may want to set up a little test program and send values to a LCD or something to play with this.

LEDave
- 14th November 2010, 23:06
You may want to set up a little test program and send values to a LCD or something to play with this.

I will, the LCD's been looking a little lonely lately. I'll let you know how I get on.

Cheers mackrackit, you're a star.

LEDave
- 14th November 2010, 23:52
~ Bitwise NOT

So it's a Bitwise NOT then (well I've never heard of that one before, I'll get straight on it)

And not:


If you don't want MicroCode Studio to interpret a control sequence, but rather send it as normal characters, then just use the tilda symbol (~) in front of the $ or # symbol. For example, letter ~#9712345 would be sent as letter #9712345.

Like I thought it was. I can be almost dangerous with my assumptions sometimes:eek:

Dave

HenrikOlsson
- 15th November 2010, 06:21
Hi Dave,
I'm jumping in here.... The docs you've quoted is the docs for MicroCodeStudio, specifically its built in terminal emulator where the ~ means what you've quoted.

But in the PBP language ~ means bitwise NOT, negate or invert - whatever you like.

GPIO.0 = ~GPIO.1 'Set GPIO.0 to the inverted state of GPIO.1

/Henrik.

LEDave
- 15th November 2010, 20:31
Hi Henrik,

Yes, NOT GATE or inverted output, here's a Wiki link for any other newbies:

http://en.wikipedia.org/wiki/Inverter_(logic_gate)

Like I said in my post above, it's easy to jump to the wrong conclusions(that's why I appreciate your and mackrackit's help so much):)

Speaking of help, I blew the dust of the old LCD and ran a modified program from mackrackits link:


MyVAR VAR BYTE
Mybyte var byte
Mybit VAR bit

LET MyByte = 7

For MyVar = 0 to 7
MyBit = MyByte.0(MyVar)
LCDOut $FE,1,"Bit ",#MyVar,"=",#MyBit
Pause 2000
Next MyVar

When I ran it, Bits 0-1-2 were 1's the rest 0's following the pattern for Bin 7:). So onto Bruce's code below:


' Only DAT_OUT bits 1 and 2 are used. We add a few 1's in bit
' positions 0,3,5,7 to balance out the data packet being sent.
DAT_OUT = %10101001
' Get data on button inputs & invert 0's to 1's
DAT_OUT.0[1]=~GPIO.3
DAT_OUT.0[2]=~GPIO.4
INTCON.0 = 0 ' Clear int on change flag

' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Well the checksum would be two BYTES of:
DAT_OUT = %10101001

With bits 1 & 2 being 0's (not inverted).....I think.



DAT_OUT = %10101001 DAT_OUT.0[1]=~GPIO.3 DAT_OUT.0[2]=~GPIO.4

Would mean (I think again) bit 1 & 2 would invert to a 1 in the DAT_OUT_BYTE. Or saying that maybe it's only bits 1 & 2 that are inverted and sent. Mm, not sure but I'll go with the first option.

Tin hat on, duck, am I close? (if not, just say so and I'll carry on thinking / reading).

Dave

mackrackit
- 16th November 2010, 02:54
Tin hat on
I wear one made of aluminum foil...


IF (GPIO.3=1) AND (GPIO.4=1) THEN
Because of this both bits in question are "1" when not pressed. So they will invert to "0".
If the thing was not sleeping that is.

But wait...

DAT_OUT = %10101001
They are "0"...

What if one of the buttons are pressed?

In the end, all eight bits of DAT_OUT are sent.

Yes, I am being a cryptic smart _ _ _. :)

LEDave
- 16th November 2010, 15:42
I wear one made of aluminum foil...

Spoken like a true engineer, even uses a ground plane as a hat:)


Yes, I am being a cryptic smart _ _ _:D

Well I know what I'll be doing tonight.... uncryptifying!

Dave

LEDave
- 17th November 2010, 17:11
It's looking like I'm going to need someone to hold my hand and gently walk me through this one as I'm confusing myself: Here's my latest piece of reasoning / thinking.....

Right then:

This is the data BYTE to be sent.


DAT_OUT = %10101001

Bruce says:


Only DAT_OUT bits 1 and 2 are used.

So at the moment they're 0 - 0.

So I'm going to leap in here and say that from the code below DAT_OUT.0[1] (bit one of the BYTE) will be equal to the inverted state of GPIO.3 (the program only gets to this piece of code after a button press though).


DAT_OUT.0[1]=~GPIO.3

And DAT_OUT.0[2] (bit two of the BYTE) will be equal to the inverted state of GPIO.4


DAT_OUT.0[2]=~GPIO.4

So taking SW1 as the button being pressed: GPIO.3 which was '1' when not pressed goes to '0' when pressed then gets inverted ~ to a '1' which becomes bit one of the BYTE.

How does that sound? North of the North pole? South of the South South pole? Or under the ice at either pole?

Dave

mackrackit
- 17th November 2010, 21:04
I'm going to need someone to hold my hand:eek:


So taking SW1 as the button being pressed: GPIO.3 which was '1' when not pressed goes to '0' when pressed then gets inverted ~ to a '1' which becomes bit one of the BYTE.Yup, you got it!

LEDave
- 17th November 2010, 21:26
I'm going to need someone to hold my hand

Well metaphorically speaking, I was beginning to panic figuring the code out.

So am I right in thinking that the DAT_OUT byte:


DAT_OUT = %10101001

Becomes:


DAT_OUT = %10101011 When SW1 is pressed.

And


DAT_OUT = %10101101 When SW2 is pressed.

The checksum:


' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Will that always be the calculated value of BYTE:


DAT_OUT.0[2]=~GPIO.4

Because this is the last BYTE to be read / run in the program sequence.

Dave

mackrackit
- 17th November 2010, 21:58
So am I right in thinking that the DAT_OUT byte:
Yes, you have all of that correct.

CHECKSUM..

Because this is the last BYTE to be read / run in the program sequence.
We are dealing with BITs here.


DAT_OUT.0[1]=~GPIO.3 'BIT #1 of DAT_OUT
DAT_OUT.0[2]=~GPIO.4 'BIT #2 of DAT_OUT

Back to what you have above that either BIT#1 or BIT#2 will be changed when a switch is pressed, DAT_OUT will be either
%10101011
or
%10101101
So...
CHK_SUM = (DAT_OUT * 2)
Will be
CHK_SUM = (%10101011 * 2)
or
CHK_SUM = (%10101101 * 2)

LEDave
- 17th November 2010, 22:31
We are dealing with BITs here.

:o

The penny has finally dropped:)

So the checksum is made up of:


DAT_OUT = %10101001 Plus the BIT that has changed *2

Cheers mackrackit, I need a lie down, I expect you do too: :eek:

I don't know how you put up with me sometimes.

Dave

mackrackit
- 17th November 2010, 22:56
I don't know how you put up with me sometimes.
:)
I remember asking that same question to a couple of folks. And I imagine you will also hear that same question.

LEDave
- 17th November 2010, 23:17
I remember asking that same question to a couple of folks. And I imagine you will also hear that same question.

:)

You know I really wish I was clever enough to help folk out, one day perhaps, one day.

Well here's some good news. That's the TX program covered and believe it or not I've got a pretty good idea of how it all works:cool:

Thing is, have you seen the RX program:eek:

So where to next mackrackit? Should I start modifying the TX - RX programs to send a 'TEST' BYTE out and receive it to simulate the Bird_Daily_Count_Total?

Or start working through the RX program?

Dave

mackrackit
- 17th November 2010, 23:32
Or start working through the RX program?
Might be a good idea to run through it. ASM is not my strong point, but Bruce has plenty of comments there.

Just to be sure we are looking at the same code, here is what I have.


'************************************************* ***************
'* Name : rfPIC_RX.BAS *
'* Author : B. Reynolds *
'* Notice : Copyright (c) 2007 Reynolds Electronics *
'* : All Rights Reserved *
'* Date : 10/09/2007 *
'* Version : 1.0 (Momentary decoder version) *
'* Notes : 2-Bit decoder for Microchip RF dev system *
'* : with rfRXD0420 module installed in PICkit 1 board *
'************************************************* ***************
@ DEVICE PIC16F676,MCLR_OFF,INTRC_OSC_NOCLKOUT,WDT_OFF,BOD_ OFF
@ DEVICE PWRT_ON,PROTECT_OFF

DEFINE OSC 4
DEFINE NO_CLRWDT 1 ' Watchdog timer is disabled, so we don't need to reset it
DEFINE OSCCAL_1K 1 ' load factory calibration value
DEFINE INTHAND RESET_VT ' Interrupt on Timer1 overflow to reset outputs in 65.5mS
' if no serial data received in this time period
SYMBOL D_IN = PORTC.1 ' data input pin
SYMBOL TMR1IF = PIR1.0 ' Timer1 overflow interrupt flag (reset in int handler)
SYMBOL TMR1IE = PIE1.0 ' Timer1 interrupt enable bit

'Variables for saving state in interrupt handler
wsave VAR BYTE $5F system ' Saves W
ssave VAR BYTE bank0 system ' Saves STATUS
psave VAR BYTE bank0 system ' Saves PCLATH
fsave VAR BYTE bank0 system ' Saves FSR

' Working variables
MATCH VAR BYTE bank0 system ' Match variable
DAT_OUTB VAR BYTE ' Holds decoded data for output
DAT_IN1 VAR BYTE ' 1st Data byte
DAT_IN2 VAR BYTE ' 2nd Data byte for verify
CHK_SUM VAR BYTE ' Holds checksum received
CheckSum VAR BYTE ' Computed checksum of all bytes received
LOOPS VAR BYTE ' Loop var

' Constants
Synch CON "~" ' 01111110 synch byte
N2400 CON 16780 ' 2400 bps inverted
N4800 CON 188 ' 4800 bps inverted

' hardware init
PORTA = 0
TRISA = %00111001 ' RA1 and RA2 are LED outputs
PORTC = 0 ' Clear outputs on power-up
TRISC = %00111110 ' RC1 = RF input
IOC = 0 ' Interrupt on change disabled
VRCON = 0 ' Comparator Vref disabled
CMCON = 7 ' Disable comparators
ANSEL = 0 ' disable A/D
OPTION_REG = 128 ' Pull-ups off

' Setup Timer1 for resets after ~65.5mS
T1CON = %00000000 ' Internal clock, 1:1 prescale, Timer1 off for now
TMR1L = 0
TMR1H = 0 ' Timer1 low & high bytes cleared
TMR1IF = 0 ' Clear Timer1 overflow flag before enabling interrupt
TMR1IE = 1 ' Enable Timer1 overflow interrupt
INTCON = %11000000 ' Global & peripheral ints enabled
MATCH = 0 ' Clear match count
GOTO MAIN ' Jump over int handler

ASM ; Timer1 overflow interrupt resets outputs when no valid key press
; is detected within ~65mS
RESET_VT
movwf wsave ; Save W
swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
movf PCLATH, W ; Move PCLATH to W
movwf psave ; Save PCLATH
movf FSR, W ; Move FSR to W
movwf fsave ; Save FSR

; Do interrupt stuff here
bcf T1CON,TMR1ON ; Stop Timer1
clrf TMR1L ; Clear low byte
clrf TMR1H ; Clear high byte
bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag bit
clrf PORTA ; Clear outputs on button release
clrf MATCH ; Clear match variable

; Restore FSR, PCLATH, STATUS and W registers
movf fsave, W ; retrieve FSR value
movwf FSR ; Restore it to FSR
movf psave, W ; Retrieve PCLATH value
movwf PCLATH ; Restore it to PCLATH
swapf ssave, W ; Get swapped STATUS value (swap to avoid changing STATUS)
movwf STATUS ; Restore it to STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it to W (swap to avoid changing STATUS)
bsf T1CON,TMR1ON ; Re-enable Timer1 before exiting interrupt handler
retfie ; Return from the interrupt
ENDASM

MAIN:
' Fire up Timer1 before entry to serial input routine
T1CON.0 = 1

' at 4MHz Timer1 overflows in 65536 * 1uS (~65.5mS) if no Synch byte
' and serial data arrive on time. SERIN2 timeout & label options
' are useless with a noisy RF receiver output - as noise continually
' resets the timeout period causing it to hang forever.

' Wait for Synch byte, then get new inbound data & checksum
SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM]

T1CON.0 = 0 ' Stop Timer1 once we've received data
TMR1L = 0 ' Clear low byte
TMR1H = 0 ' Clear high byte

' / **** Begin data validation **** /

' Calculate checksum by adding 2 data bytes together
CheckSum = DAT_IN1 + DAT_IN2

' Test new checksum against one received in CHK_SUM
IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return

' Test data bytes for match
IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return

MATCH = MATCH + 1 ' We have a match so increment match count
IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good
GOTO Main ' Else do it all over

' Everything looking good - so place new data on outputs
DECODE:
' Place decoded values on port pins..
PORTA = DAT_IN1 & %00000110
DAT_IN1 = !DAT_IN2 ' Destroy the match
MATCH = 0
GOTO MAIN

END

LEDave
- 17th November 2010, 23:58
That's the one.

An awful lot of new stuff there. Now I'm thinking should I really jump in and start to learn a little Assembly as well?

That's where I was in February trying to light my first LED.... The rest is history as they say. I remember reading the Microchip stuff saying there was only 35 instruction words to learn (I'm sure I read that somewhere) and thinking to myself "How difficult can that be"......lol.

Well you're getting to know me now mackrackit, slow, not very bright but determined!

I'm game if you are.

Dave

mackrackit
- 18th November 2010, 00:17
I think for now being able to read the ASM code enough to understand what is going on will be enough. Then learn how to write some of it later.

Have you done anything with interrupts yet? That is what the ASM is doing in this code.

LEDave
- 18th November 2010, 00:33
Have you done anything with interrupts yet? That is what the ASM is doing in this code.

We have touched on it, we did a timing loop interrupt program (it might have been before I bought the full PBP program) so quite a while back .

So where to start then?

mackrackit
- 18th November 2010, 00:49
So where to start then?
At the top... ;)

The PBP manual has a section in the back about interrupts in ASM, Read it along with the code.
Basically, when an interrupt is called things have to be saved so the program can pickup where it left off while dealing with the interruption. Have you ever received a phone call and when the call was over forgot what you were doing when the call came in? We do not want the PIC to have that problem.

LEDave
- 18th November 2010, 23:40
Have you ever received a phone call and when the call was over forgot what you were doing when the call came in? We do not want the PIC to have that problem.

I've had conversations lately where I've gone off track for a moment and completely forgot the main thread of what I was saying, I think the Interrupt handler in my brain need dubugin:eek:


The PBP manual has a section in the back about interrupts in ASM, Read it along with the code.

Page 200 in the manual, I'm reading it and trying to work through the code. Bruce's code is exactly the same well very similar, with the Interrupt block in the middle added.

Thanks for the pointer mackrackit.

Dave

LEDave
- 20th November 2010, 23:34
Here's my take on what's going on. From the top:


T1CON = %00000000

Pre-scale Bits 4 & 5 set at zero for 65536 count - TMR1ON bit zero set to zero (not on).


TMR1IE = 1

But: TMR1IE = PIE1.0 so PIE1.0 = 1


INTCON = %11000000

bits 6 & 7 Peripheral & global interrupt bits set.


MAIN:
' Fire up Timer1 before entry to serial input routine
T1CON.0 = 1

So Timer1 bit.0 = 1 Timer1 turned on and count starts........

If the count reaches 65536ms then the Interrupt flag TMR1IF PIR.0 goes to 1 then the program jumps to:


DEFINE INTHAND RESET_VT

I think this a kind of GOTO ASM in 65.5ms (Timer1) if no data comes in. If data had come in the program would have continued.

Not very well explained I'm afraid, how did I do..........?.....Gulp.

Dave

mackrackit
- 21st November 2010, 10:08
Sounds pretty good to me. :)

A point though..
RESET_VT
inside the ASM part of the code is an ASM label.
DEFINE INTHAND RESET_VT
Tells where to go when the interrupt occurs.

LEDave
- 21st November 2010, 14:17
Hi mackrackit.

My mistake, I should have said:


If the count reaches 65536ms then the Interrupt flag TMR1IF PIR.0 goes to 1 then the program jumps to:


RESET_VT

Not the DEFINE.

So when the program jumps after PIR.0 = 1 to RESET_VT it then runs the Register saving code, then the INTERRUPT routine, then restores all the previously saved values back to exactly the same condition as pre - RESET_VT. Can we come back to that part the ASM stuff later but for now assume there was some DATA received and the next block of PBP code.

Dave

mackrackit
- 21st November 2010, 14:35
Can we come back to that part the ASM stuff later but for now assume there was some DATA received and the next block of PBP code.
Yup, sounds like you have the interrupt idea worked out.
On to MAIN...

LEDave
- 21st November 2010, 15:51
MAIN:
' Fire up Timer1 before entry to serial input routine
T1CON.0 = 1

So the Timer1 is running and we've got 65.5ms to receive the data.

I guess a question here would be how fast does a PIC receive DATA? At the moment we're only receiving the SYNCH - DAT_IN1 - DAT_IN2 & CHK_SUM BYTES. If for example when the project is running and we send accumalative Bird Box Visit_Data (day1 + day2 etc.....n) then after a Month we'd have 30 Bytes or Words even, would that time_out? Because as the program stands:


T1CON.0 = 0

After the Data has arrived.

Anyway moving on.

So the Data has arrived:


SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM]


Then:


T1CON.0 = 0 TMR1L = 0 TMR1H = 0

So Timer1 is stopped - TMR1H&L BYTES cleared.

Before I carry on with **Begin Data Validaition**

What does the ! in: IF CheckSum ! mean please mackrackit.

Dave

mackrackit
- 21st November 2010, 18:22
Manual section
4.18. Comparison Operators
Not equal !=


I guess a question here would be how fast does a PIC receive DATA?

I think once the PIC starts receiving with SERIN2 it will not stop till finished. I will have to check to be.

LEDave
- 21st November 2010, 23:08
Manual section
4.18. Comparison Operators
Not equal !=

Cheers mackrackit, thanks for the pointer.

Dave

LEDave
- 22nd November 2010, 17:56
Calculate checksum by adding 2 data bytes together


CheckSum = DAT_IN1 + DAT_IN2

So the CheckSum = (%10101011 * 2 BYTES) if SW1 ( GPIO.3) was pressed.

or (%10101101 * 2 BYTES) if SW2 (GPIO.4) was pressed.

Plus we should have the already have a calculated CHK_SUM that was sent.

So:


CHK_SUM VAR BYTE ' Holds checksum received

And:


CheckSum VAR BYTE ' Computed checksum of all bytes received

Therefore:


IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return

If Checksum (!) is not = CHK_SUM then go back to MAIN the checksum has failed.

The same with:


IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return

The DAT_IN BYTES must also be equal, if not then back to MAIN:

If however everything matches then continue to MATCH..........

How does this look?

Dave

LEDave
- 22nd November 2010, 22:14
Another question:


wsave VAR BYTE $5F system ' Saves W

Bruce's code talks of Bank0 system. Am I correct in saying that BYTE $5F system is setting bit.5 of the STATUS REG to 0 which is selecting Bank0 ($5f = %1011111).

So to change from Bank0 to Bank1 would be %1111111

Also:


movwf wsave ; Save W

So these commands mean Move the contents of the W REG to the address of wsave.

Mm, not really sure about this............(more reading to do).

Dave


Dave

mackrackit
- 22nd November 2010, 23:31
The DAT_IN BYTES must also be equal, if not then back to MAIN:

If however everything matches then continue to MATCH..........

How does this look?
I think you got that part down.


Bruce's code talks of Bank0 system. Am I correct in saying that BYTE $5F system is setting bit.5 of the STATUS REG to 0 which is selecting Bank0 ($5f = %1011111).

So to change from Bank0 to Bank1 would be %1111111
Like I said, ASM is not my strong point. Not sure I have a strong point...
Below tells how to change banks, I think.

If the PICmicro has more than 2K of code space, an interrupt stub is automatically added that saves the W, STATUS and PCLATH registers into the variables wsave, ssave and psave, before going to your interrupt handler. Storage for these variables must be allocated in the BASIC program:

wsave var byte $20 system
wsave1 var byte $a0 system ' If device has RAM in bank1
wsave2 var byte $120 system ' If device has RAM in bank2
wsave3 var byte $1a0 system ' If device has RAM in bank3
ssave var byte bank0 system
psave var byte bank0 system




movwf wsave ; Save W
So these commands mean Move the contents of the W REG to the address of wsave.
Yes.
Also notice that all of the data is restored in the opposite sequence it was saved.

If I am giving wrong ASM info , somebody please jump in and correct me!

LEDave
- 22nd November 2010, 23:55
Hi mackrackit,


Not sure I have a strong point...

Hey, you put up with me, so patience is one of them;)

And don't forget it was trying to turn an LED on using ASM that after a near breakdown put me onto PBP:D

I'll go onto MATCH & DECODE tomorrow, slowly getting there (slowly).

Dave

LEDave
- 23rd November 2010, 14:37
It still doesn't take much to stump me I'm afraid........:(


MATCH = MATCH + 1 ' We have a match so increment match count
IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good
GOTO Main ' Else do it all over

When the Timer was set up for a 65ms reset we had:


MATCH = 0 ' Clear match count

Then the SYNCH_BYTE & DATA etc arrived and everything was good giving:


MATCH = MATCH + 1 ' We have a match so increment match count

So to my mind that makes MATCH = 0 +1 ie 1.

But then we have:


IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good

So either the data arrives twice within the 65ms time period to move onto DECODE or my understanding of MATCH = MATCH + 1 is wrong.

Help!

Dave

mackrackit
- 24th November 2010, 09:26
So either the data arrives twice within the 65ms time period to move onto DECODE or my understanding of MATCH = MATCH + 1 is wrong.
Not within the 65ms but just twice. MATCH does not get set to zero until DECODE is reached.
One good set of data could arrive then many not-goods, then one more good THEN DECODE.

Being this came from Bruce it is hard for me to question it but....
Here is what I think it should be


' Test new checksum against one received in CHK_SUM
IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return
MATCH = MATCH + 1 ' We have a match so increment match count

' Test data bytes for match
IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return
MATCH = MATCH + 1 ' We have a match so increment match count

IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good
GOTO Main ' Else do it all over

LEDave
- 24th November 2010, 16:13
Far more intuitive for a newbie your way mackrackit. I would have been stuck in a loop looking for a second MATCH until my watchdog timer kicked in (that's not to say Bruce's program isn't pure genius from where I'm sitting).

I'm thinking that if one MATCH had occurred but was followed by bad data, then the ASM :


clrf MATCH ; Clear match variable

would reset the single MATCH to zero after 65ms?

Onto DECODE then.

Dave

LEDave
- 24th November 2010, 19:01
' hardware init
PORTA = 0
TRISA = %00111001 ' RA1 and RA2 are LED outputs

So PORTA.1-2 are outputs

And BYTES received will be
%10101011 or %10101101


PORTA = DAT_IN1 & %00000110

The manual says:Bitwise Operators: & %00000001 ' Isolate bit 0 of BYTE.

So I'm thinking: & %00000110 ' Isolate bits 1 & 2, would give:

%00000010 from %10101011 & %00000100 from %10101101 as PORTA, depending on which button was pressed and light the LED's.

Hot, cold or tepid?

Dave

mackrackit
- 25th November 2010, 09:10
Hot, cold or tepid?
Hot :)
Looks like you got it.

BTW, I missed

clrf MATCH ; Clear match variable
So the original code would have to receive two good with out a bad. I wonder why Bruce did it that way?

LEDave
- 25th November 2010, 14:48
Cheers mackrackit:)


So the original code would have to receive two good with out a bad. I wonder why Bruce did it that way?

I don't know.....

One thing though, from Bruce's code (and please bear in mind this is the thinking of a newbie here).The only way(as I see it) that MATCH can ever reach a count of two and then move onto 'DECODE' is for the program to run from 'SERIN2' all the way to 'GOTO Main' once and then a second time to 'IF MATCH = 2 THEN DECODE' for MATCH to ever equal 2. Am I missing something here?


' Wait for Synch byte, then get new inbound data & checksum
SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM,TEST]

T1CON.0 = 0 ' Stop Timer1 once we've received data
TMR1L = 0 ' Clear low byte
TMR1H = 0 ' Clear high byte

' / **** Begin data validation **** /

' Calculate checksum by adding 2 data bytes together
CheckSum = DAT_IN1 + DAT_IN2

' Test new checksum against one received in CHK_SUM
IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return

' Test data bytes for match
IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return

MATCH = MATCH + 1 ' We have a match so increment match count
IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good
GOTO Main ' Else do it all over

Dave

mackrackit
- 25th November 2010, 16:36
One thing though, from Bruce's code (and please bear in mind this is the thinking of a newbie here).The only way(as I see it) that MATCH can ever reach a count of two and then move onto 'DECODE' is for the program to run from 'SERIN2' all the way to 'GOTO Main' once and then a second time to 'IF MATCH = 2 THEN DECODE' for MATCH to ever equal 2. Am I missing something here?
Yep, that is what I see also.
Maybe Bruce set this up to test how reliable the connection is? If it can do two before the interrupt time out then the connection is solid.

LEDave
- 25th November 2010, 17:22
Maybe Bruce set this up to test how reliable the connection is? If it can do two before the interrupt time out then the connection is solid.

Yes, could well be.

Well I've learnt a lot from going through the TX / RX program code.

There were a lot of new terms which I hadn't come across (very clever in what they did / do though) which all adds to the knowledge base.

So to summarise:

The TX is an Interrupt_On_Change program which sleeps to save power until a button press is received.

The RX is a Timer(65ms) Interrupt_loop, which resets if no Data_In is received within the time period.

Just to be clear in my own mind here, there are two ways to reset the RX Interrupt Timer. One in Main:


T1CON.0 = 0 ' Stop Timer1 once we've received data
TMR1L = 0 ' Clear low byte
TMR1H = 0 ' Clear high byte

Which does it when Data is received (TMR1L/H will have a value of less that 65536 before reset).

The other in the Interrupt_Handler 'RESET_VT' which the program would jump to on a Time_Out.

If the above is accurate and makes sense, then in the time honoured tradition:

What's next?:)

Dave

mackrackit
- 25th November 2010, 18:11
What's next?
Send some data other than LED on/off stuff and display the received data on a terminal and/or save to EEPROM. :)

LEDave
- 25th November 2010, 18:33
Send some data other than LED on/off stuff and display the received data on a terminal and/or save to EEPROM.

Ah, the TX project program begins............:D

LEDave
- 26th November 2010, 19:34
I've made a few changes to the TX / RX programs. I can now send a BYTE called TEST with the value 7, which is received and flashes an LED to the value of the BYTE.

I know I'm the probably the only person on this FORUM who didn't know if this would work but I thought why not make the count 1 TO n the value of TEST and it worked a treat.


lED:
for X = 1 to TEST 'Test=7
HIGH PORTA.1
PAUSE 500
LOW PORTA.1
pause 500
next X
GOTO MAIN

Another step forward.

Dave

mackrackit
- 27th November 2010, 13:03
COOL!!!
Do you have it set up so one button sends a value and the other button sends a different value?

LEDave
- 27th November 2010, 17:48
Hi mackrackit,


Do you have it set up so one button sends a value and the other button sends a different value?

No, not at present. At the moment either button press will send the value seven (I've made a few code changes), the receiver code then runs the loop and counts / flashes the led seven times.The test is the value sent & received must = 7 or nothing will happen (and it does).....:D

LEDave
- 30th November 2010, 21:52
I found this on a nest box website regarding the number of visits or rather the amount of food the parents bring to the young:


Each chick can eat 100 caterpillars a day, so adults need to find as many as 1000 caterpillars a day for a brood of 10!

So with this in mind a WORD would be needed as a counter, so I've modified the code to send a WORD instead of a BYTE and added a test number (600):


TEST VAR word

LET Test = 600

SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,TEST.HIGHBY TE,TEST.LOWBYTE]

And for the receiver:


TEST var word

X VAR BYTE

SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM,TEST.HIGHBYTE, TEST.LOWBYTE]

IF TEST = 600 THEN LED
GOTO MAIN

lED:
for X = 1 to TEST 'Test = 600
HIGH PORTA.1
PAUSE 500
LOW PORTA.1
pause 500
next X
GOTO MAIN

END



And it works, the led flashes 600 times (I know I've counted them);)

Another small step nearer.

Dave

mackrackit
- 1st December 2010, 00:37
And it works, the led flashes 600 times (I know I've counted them)
That is a heck of a lot of caterpillars!!!!!! :eek:

LEDave
- 1st December 2010, 03:40
That is a heck of a lot of caterpillars!!!!!!:eek:

Lol...........Can't be too careful here though, checkout the link below;)

http://www.arkive.org/cuckoo/cuculus-canorus/video-09c.html

I need to do some thinking for the next part of the program. I'm going to need another pin as an input for the counter from the sensor and another pin as an input from an LDR to tell the PIC when it's dark and send the days count_data over. I guess I won't be able to use the two pins with buttons on (GPIO.3/4).

Question: How quick does a PIC wake_up from sleep with an IOC?

Steadily moving along.

Dave

mackrackit
- 1st December 2010, 13:37
That bird doing the feeding better not fall into the nest, it might end up being lunch...


Question: How quick does a PIC wake_up from sleep with an IOC?
@SLEEP
From a data sheet

The power-down Status bit, PD is
cleared. Time-out Status bit, TO
is set. Watchdog Timer and its
prescaler are cleared.
The processor is put into Sleep
mode with the oscillator stopped.
But even though the OSC is stopped the IOC pin(s) are still active. When the changes occurs the device "wakes up".

The PBP SLEEP command is different. The device will sleep for a given time period.

So I think to answer the underlying question... You only need one of the buttons.

LEDave
- 1st December 2010, 18:03
Thanks for that mackrackit.

I was thinking that the TX will work in a kind of fully automatic mode, no actual button pressing to transmit the days data_count over. The trigger for this would be the LDR sensing it's dark(so no more feeds / visits) turning a pin high that then triggers the transmit.

This the pin-out as is stands is below:

GPIO.0 - Pot - R1
GPIO.1 - Pot - R2
GPIO.2 - Data_out
GPIO.3 - SW2
GPIO.4 - SW1
GPIO.5 - RF_Enable

So I'm thinking I need two more input pins (one for the sensor the other for the LDR) Pots R1 - R2 look favourite to me, do you think they'd be ok as inputs.

Dave

mackrackit
- 1st December 2010, 19:05
Maybe I am missing something..
Do you want data sent at each sensor trigger?
Have the sensor on one of the pins currently used for a switch.

LEDave
- 1st December 2010, 19:58
Hi mackrackit


Do you want data sent at each sensor trigger?

No I don't think so, a whole days visits in one transmit will do the job.


Have the sensor on one of the pins currently used for a switch.

Well initially I thought ah, just bye-pass the switch then thought I can't do that as it's in series with the pin but once again you inspire me mackrackit, RA3 / 4 bye-pass the switches straight onto GPIO.3 / 4 the switches are connected to ground when pressed (if that makes sense):) so looking good to go.


That bird doing the feeding better not fall into the nest, it might end up being lunch...

I know, you gotta feel for the feeder, overworked or what:eek:

I almost forgot, I've had a look at RS / Maplins for a product similar to header J3, it would be really handy to be able to just plug the RX / TX modules in and out but can't find anything, I'm going to email Microchip and ask them for a UK supplier and spec.

Dave

mackrackit
- 1st December 2010, 21:41
Do you have mouser over there?
If so look at type "D"
http://www.mouser.com/catalog/catalogUSD/642/1419.pdf

LEDave
- 1st December 2010, 22:58
Mouser Electronics
Artisan Building
Suite C, First Floor
Hillbottom Road
High Wycombe
Buckinghamshire
HP12 4HJ
United Kingdom

Looks like we do:D

I'll just double check, this is the part? (see attachment) I'll be onto then tomorrow (I wonder if they do a 90 degree one?).

You're a star mackrackit.

Dave

LEDave
- 8th December 2010, 22:40
Have got the night time trigger to send the Visits_total over from the TX to RX working.

It works on a 555 timer chip instead of an op-amp Schmitt trigger (very handy same voltage for 555 & PIC).The cct dia is below(see attachment). Only needed to add an ORP12 - LDR and a 10k resistor across the input, might have to tweak the resistor value but works a treat with my hand acting as approaching darkness.

Another step forward.

Dave

mackrackit
- 9th December 2010, 02:47
COOL!!!!

Not having seen your code so maybe you have this or considered this...

It is easy to have false triggers when sensing light, sensing "dark" at dusk could give trouble. You may want to incorporate a timer of some kind not to send the data until you are "sure" it is dark. The dark trigger has to be active for 30 minutes???

What if there is a bug on the sensor?? A real bug...

LEDave
- 9th December 2010, 14:57
Hi mackrackit



It is easy to have false triggers when sensing light, sensing "dark" at dusk could give trouble. You may want to incorporate a timer of some kind not to send the data until you are "sure" it is dark. The dark trigger has to be active for 30 minutes???

Mm, how about sending the PIC back to SLEEP awaiting another Interrupt_On_Change (the birds have started visiting again it was only a cloud) so carry on counting. If after say SLEEP 1800(about half an hour) the LDR is still high then Send_Data it really is dark!


What if there is a bug on the sensor?? A real bug...

Oh dear, Badgers I don't mind (even Bears seem kind of cuddly) but bugs!!!:eek:

I think the code would have to be something like:


IF Count_Input_Pin is HIGH for >50ms THEN SEND:

SEND:

'Mrs LEDave into the garden and clean the sensor.

RETURN.

That's an interesting point though because the Birds don't always fly straight into the nest box they quite often hang by the hole then enter so the timing(or lenght of time) of the INPUT COUNTER will need some thinking about.

Dave

mackrackit
- 9th December 2010, 20:45
I have not been able to program Mrs. Mackrackit. Fuzzy logic :eek:


Mm, how about sending the PIC back to SLEEP awaiting another Interrupt_On_Change (the birds have started visiting again it was only a cloud) so carry on counting. If after say SLEEP 1800(about half an hour) the LDR is still high then Send_Data it really is dark!
That should work.


the INPUT COUNTER will need some thinking about.
"Debounce" so one count per bird...

LEDave
- 9th December 2010, 22:32
I have not been able to program Mrs. Mackrackit. Fuzzy logic

Lol, I think we're starting to skate on thin ice here:D


That should work.

I sometimes wonder is there a 'best of practise' when it comes to programming - Then again I'm still pretty much at the 'if it works I'm happy' stage of things......


"Debounce" so one count per bird...

Ah, I remember Debounce.

Right then, onto the sensor input / count.

Dave

mackrackit
- 10th December 2010, 00:09
I sometimes wonder is there a 'best of practise' when it comes to programming
Yup, it is called seeing how Darrel or Bruce would do it..


Then again I'm still pretty much at the 'if it works I'm happy' stage of things......Me too!

LEDave
- 12th December 2010, 00:28
Problem:

I'm using SLEEP uncalibrated to put the PIC to SLEEP until an IOC occurs earlier on in the program. I'm also using SLEEP 1800 to put the PIC to sleep and test that it's still dark before transmitting the VISITS data. I'm getting an error when I compile the program though (see attachment). I've turned the _WDT_ON but still this error. Any ideas? Is using SLEEP an SLEEP Period in the same program uncompatable?


DARK:
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' Clear int on change flag
@ SLEEP 1800 ' It could be night time...It might only be a cloud though...
' so back to sleep for half an hour..zzzz
@ NOP ' Do nothing for 1st instruction on wake-up

if GPIO.4= 0 then ENCODE ' It really ia dark so carry on and transmit VISITS

IF GPIO.4= 1 THEN RETURN ' It's not dark after all so carry_on_counting

Forgot to add, if I comment out the line:


@ SLEEP 1800 ' It could be night time...It might only be a cloud though...

the program compiles

Dave

mackrackit
- 12th December 2010, 02:15
@SLEEP can not be used like that. The OSC is stopped when sleeping so it would not know what to do with it.

But... Bruce to the rescue again.
http://www.picbasic.co.uk/forum/showthread.php?t=7013

LEDave
- 13th December 2010, 23:31
Hi mackrackit


But... Bruce to the rescue again.

I must add him to my Christmas card list too.....!

So @SLEEP (no period) for the visits count with IOC and a WDT timing loop for the "is it dark or just very cloudy" 30 min sleep.


OPTION_REG = %00001111

So with OPTION reg bit.4 set to 1 prescaler assigned for WDT on and a 128 prescaler I'm thinking that:

30mins x 60sec / 2.304secs = 781 counts for Bruce's timing / SLEEP loop below.


COUNTER=0 ' clear before entry
WHILE COUNTER < 781
@ SLEEP
COUNTER=COUNTER+1
WEND

So not really sleeping, more power napping.........

How does the above sound / look.

Dave

mackrackit
- 14th December 2010, 06:31
So not really sleeping, more power napping.........
That is what I was doing while driving home today....

How does the above sound / look.
Looks like it should work.
And you say that you have been doing this less than a year.

LEDave
- 14th December 2010, 10:51
That is what I was doing while driving home today....:eek:

Careful, we don't want any incidents now do we...!


And you say that you have been doing this less than a year.

A year February from memory, I think the progress made has been down to the tutors as much as the pupil.

Dave

LEDave
- 15th December 2010, 21:28
Ok,

Time to stick my neck out and say I think (I think) I've finished the TX / RX programs. I haven't connected them to the sensor / LDR to test for operation but I'd be very interested as to whether you can see any gaping errors in the code, here goes, TX first:


'************************************************* ***************
'* Name : rfPIC_TX.BAS *
'* Author : B. Reynolds 90% LEDave 10%...Ok 5% *
'* Notice : Copyright (c) 2007 Reynolds Electronics *
'* : All Rights Reserved *
'* Date : 10/09/2007 *
'* Version : 1.0 *
'* Notes : 2-BIT Encoder for remote control with the *
'* : rfPIC12F675 on Microchip rfPIC demo board *
'************************************************* ***************
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF

DEFINE OSC 4
DEFINE NO_CLRWDT 1
DEFINE OSCCAL_1K 1

SYMBOL D_OUT = GPIO.2 ' RF serial data output
SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output


VISITS VAR word ' Holds total daily bird visits
DAT_OUT VAR BYTE ' Holds 8-bit data byte
DAT_OUT2 VAR BYTE ' Holds 8-bit test byte
LOOPS VAR BYTE ' Loop var
CHK_SUM VAR BYTE ' Holds calculated checksum of outbound data
COUNTER VAR BYTE ' Holds WDT count values
BAUD VAR WORD ' Holds baud rate

' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte
N4800 CON 188 ' 4800 bps
N2400 CON 16780 ' 2400 bps
GUARD CON 5 ' 5mS guard time pause


' hardware init
GPIO = 0 ' Everything off on boot
' GPIO.2=data out, GPIO.5=RF enable, GPIO.3,4 = Bird_visit_count / It's dark..maybe
TRISIO = %00011011 '
ANSEL = 0 ' Disable A/D
INTCON = %00001000 ' Enable port change wakeup from sleep
WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)
IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4
VRCON = 0 ' Disable internal Vref
CMCON = 7 ' Disable comparators
OPTION_REG = %00001111 'Watch_Dog_Timer ON with a 128 prescaler


D_OUT = 0 ' Idles low for inverted serial output
E_OUT = 0 ' Enable for RF transmitter=0 (transmiter off)
BAUD = N2400 ' Set baud rate here

Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.

IF GPIO.3= 1 AND GPIO.4= 1 THEN ' Nothing has happened so SLEEP
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No Bird detected or it's still light so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz indefinatly
@ NOP ' Do nothing for 1st instruction on wake-up
ELSE
IF GPIO.3=0 THEN GOSUB COUNTS 'Bird detected at box - GOTO LABEL COUNTS
IF GPIO.4=0 THEN GOSUB DARK 'It's got dark? or just cloudy - GOTO LABEL DARK
ENDIF
GOTO MAIN 'Back to sleep / continue counting


COUNTS:
VISITS = VISITS +1 'Bird at box so increment counter
INTCON.0 = 0 ' Clear int on change flag
RETURN ' Then back to sleep....

DARK:
INTCON.0 = 0 ' Clear int on change flag
E_OUT=0 ' Disable transmitter
' It could be night time...It might only be a cloud though...
' so back to sleep / wake / sleep for half an hour..zwzwzw
COUNTER=0 ' clear before entry
WHILE COUNTER < 781 'Loop for 30 mins
@ SLEEP
COUNTER=COUNTER+1
IF GPIO.3= 0 THEN COUNTS 'Bird at box so continue counting
WEND

if GPIO.4= 0 then ENCODE ' It really ia dark so carry on and transmit VISITS

IF GPIO.4= 1 THEN RETURN ' It's not dark after all so carry_on_sleeping_counting

Encode:
E_OUT=1 ' Turn transmitter on
pauseus 25 ' Let transmitter settle
DAT_OUT = %10101001
INTCON.0 = 0 ' Clear int on change flag

' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
LET VISITS = VISITS / 2 'Just VISITS to not from the box
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,VISITS.high byte,VISITS.lowbyte]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.

GOTO Main

END


Dave

mackrackit
- 15th December 2010, 23:11
I do not see anything obviously wrong. Should work.

LEDave
- 15th December 2010, 23:54
Cheers mackrackit,

I guess the next thing is to wire it up and see what happens....:eek:

One thing that has become very apparent to me with programming is that due to the permutations / complexity of a program, an error can easily slip in and be very difficult to identify, almost like a sleeping time bomb. I hope the TX program is glitch free, we shall see.

Dave

mackrackit
- 16th December 2010, 00:37
That is part of the reason I write in blocks.

Write a block test a block.

Then stack the blocks up when they are all good.

LEDave
- 16th December 2010, 10:28
That is part of the reason I write in blocks.

Seems obvious when I read it. I think I get newbie-itus (symptoms: rapid typing and tunnel vision + a feeling of excitement) when I can see the end of or the way through a project and just leap in. Blocks make total sense.

Dave

Bruce
- 16th December 2010, 12:21
I would remove DEFINE NO_CLRWDT 1

You want PBP to handle clearing WDT for you when you have the watchdog enabled.

LEDave
- 16th December 2010, 15:46
You want PBP to handle clearing WDT for you when you have the watchdog enabled.

Thanks for that Bruce and for putting the TX / RX programs up in the first place.

Dave

LEDave
- 28th March 2011, 23:28
Hi all,

Have been very busy with other things for a few Months now, things seem to have settled enough now though for me to be able to get on with the project (long overdue).

These last few nights I've been building the project intergrating the rfpic module, ldr night cct sensor and VB program. Things arn't going smoothly though, everything worked well on the breadboard but not in the finished cct.....I'll get there though.

Really pleased to be back.

Dave

LEDave
- 4th April 2011, 16:40
I'm having major problems trying to get the TX program to do what I want it to, namely TX after a timing loop executes. Just for information, if I comment out the timing loop the program TX's no problem and sends and receives a test WORD.

Here's the setup:


INTCON = %00001000 ' Enable port change wakeup from sleep


WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)

It's GPIO.4 we're looking at here. That's the pin that will receive the input from a 555 timer / potential divider using an ldr to detect that it's dark and therefore TX the days count over.


OPTION_REG = %00001111 'Watch_Dog_Timer ON with a 128 prescaler

Here's the main body of the program. it's a little bit of a mess because I've commented out the GPIO.3 COUNTS part of the program and also added then commented out INTCON.0 = 0 in various places to try and get it to do the timer loop / COUNT then TX.


IF GPIO.3= 1 AND GPIO.4= 1 THEN ' Nothing has happened so SLEEP
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No Inputs detected or it's still light so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz indefinatly
@ NOP ' Do nothing for 1st instruction on wake-up
ELSE
'IF GPIO.3=0 THEN GOSUB COUNTS 'Bird detected at box - GOTO LABEL COUNTS
IF GPIO.4=0 THEN DARK 'It's got dark? or just cloudy - GOTO LABEL DARK
ENDIF
GOTO MAIN 'Back to sleep / continue counting


'COUNTS:
' VISITS = VISITS +1 'Bird at box so increment counter
' INTCON.0 = 0 ' Clear int on change flag
'RETURN ' Then back to sleep....

DARK:

'INTCON.0 = 0 ' Clear int on change flag
' It could be night time...It might only be a cloud though...
' so back to sleep / wake / sleep for half an hour..zwzwzw

COUNTER=0 ' clear before entry
WHILE COUNTER < 2 ' 4.608sec Loop time (Loop for 30 mins = 781)
@ SLEEP
COUNTER=COUNTER+1
'IF GPIO.3= 0 THEN COUNTS 'Bird at box (it's not dark) so continue counting
WEND

if GPIO.4= 0 then ENCODE ' It really ia dark so carry on and transmit VISITS

'IF GPIO.4= 1 THEN Main '(changed from return) It's not dark after all so carry_on_sleeping_counting

Encode:
E_OUT=1 ' Turn transmitter on
pauseus 25 ' Let transmitter settle
DAT_OUT = %10101001

'INTCON.0 = 0 ' Clear int on change flag

'Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
'LET VISITS = VISITS / 2 'Just VISITS too not from the box
LET VISITS = 300 'Test data number
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,VISITS.high byte,VISITS.lowbyte]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.
INTCON.0 = 0 ' Clear int on change flag - moved here from above
GOTO Main

END


I think the problem maybe that the COUNTER loop never gets completed because the IOC which comes from GPIO.4 isn't reset and the counter loop is using @SLEEP but never gets that far.

Any ideas greatfully received.

Dave

mackrackit
- 4th April 2011, 20:19
What happens if the @SLEEP below is commented?


WHILE COUNTER < 2 ' 4.608sec Loop time (Loop for 30 mins = 781)
@ SLEEP
COUNTER=COUNTER+1
'IF GPIO.3= 0 THEN COUNTS 'Bird at box (it's not dark) so continue counting
WEND

LEDave
- 4th April 2011, 21:32
What happens if the @SLEEP below is commented?


It TX's straight away and the led on the Pickit1 (receiver) flashes three times (as intended). There is no 5 sec delay from the timing loop though.

It's as if the timing loop COUNT is just being bypassed, have I set it up right?

Dave

LEDave
- 4th April 2011, 22:36
If I press and hold down push button GP4 on the transmitter, the receiver flashes the led continually. I would have thought / was expecting that when the push button on GPIO.4 was pressed and held down you would get a four / five second delay before the receiver received anything and started to flash.

Tonights silly question:

How does setting the OPTION reg and WDT then become associated with the loop COUNTER? The WDT has a period of 18ms so setting the bits 111 gives 128*18ms =2.304secs the COUNTER loop should run twice giving a delay of 4.608secs right? But if the program doesn't read COUNTER as being associated with the WDT it's going to count to two in a flash and it will appear that the TX sends the data instantly(which is what is happening). Should the WDT and COUNTER be 'joined' via a 'SYMBOL statement in the program under SYMBOL? or something like this?

Dave

mackrackit
- 5th April 2011, 14:10
Just guessing as I have not done this before...


WHILE COUNTER <= 2 ' 4.608sec Loop time (Loop for 30 mins = 781)
INTCON.0 = 0
@ SLEEP
COUNTER=COUNTER+1
'IF GPIO.3= 0 THEN COUNTS 'Bird at box (it's not dark) so continue counting
WEND

I hope someone else will jump in on this...

LEDave
- 5th April 2011, 18:06
Hi mackrackit,

I've made the changes and the Transmitter lights the it's reference led about once every nine seconds but doesn't transmit at all (doesn't seem to get that far).

I still can't get my head around how the WDT associates with the loop COUNTER, plus the more I read on this it seems that if the WDT isn't reset back to zero before it reaches FF+1 (I think) it then reboots the program which makes sense....Mmm, more reading and thinking to do, interesting though.

Dave

cncmachineguy
- 5th April 2011, 19:05
First let me say, this is an awesome thread. I have been meaning to read it from the beginning, but I am a slow reader.

LEDave, WDT in the snippet you just posted works like this:
Assuming PBP knows you are using the WDT, clear WD is sprinkled around the program for you to keep from resetting the chip. But to get to these, the program must run.

@sleep basically stops the program and the chip just, well sleeps. Because of this, the WDT never gets cleared. The WD can wake up the PIC, so when WDT overflows, the PIC wakes up and resumes where it left off. So this is how the WDT is associated with the counter.

Hope this helps

mackrackit
- 5th April 2011, 19:36
Bert,
will this make it work as expected?


WHILE COUNTER <= 2 ' 4.608sec Loop time (Loop for 30 mins = 781)
INTCON.0 = 0
@ SLEEP
CLEARWDT
COUNTER=COUNTER+1
'IF GPIO.3= 0 THEN COUNTS 'Bird at box (it's not dark) so continue counting
WEND

cncmachineguy
- 5th April 2011, 19:58
Dave, sorry for being only clear as mud with my explaination. I ment to say : because of this, the WD never gets cleared WHILE SLEEPING. When the pic is asleep, WDT overflows thus waking up the PIC.

I tried to quickly look over the program a few posts up, but I don't have a good feel for it yet. I don't think adding the CLRWDT will help only because when the pic wakes, it should be a long time (~2sec) before the next overflow.

I did notice when @SLEEP is used elsewhere in the program, the line following is @NOP. Maybe this is needed to give the pic a chance to get the sleep from its eyes? I would try using @NOP right after the @SLEEP and see if this works.

I have never used any of the power saving modes before, but if the pic needs a nop upon waking up, it may be ignoring the counter=counter+1. Therefore the while is never satisified.

In any event,if the NOP is needed, adding CLRWDT may solve the problem, we just won't know why it did.

LEDave
- 5th April 2011, 21:51
Hi Bert

Thanks for your input and welcome to the thread. I was heading towards the CLRWDT after reading this (quite an interesting website):

http://www.hobbyprojects.com/pic_tutorials/tutorial13.html

Well here's the section of code as it stands:


DARK:
'INTCON.0 = 0 ' Clear int on change flag
' It could be night time...It might only be a cloud though...
' so back to sleep / wake / sleep for half an hour..zwzwzw

COUNTER=0 ' clear before entry
WHILE COUNTER <= 2 ' 4.608sec Loop time (Loop for 30 mins = 781)
INTCON.0 = 0 ' Clear int on change flag
@ SLEEP
@ NOP
CLEARWDT
COUNTER=COUNTER+1
'IF GPIO.3= 0 THEN COUNTS 'Bird at box (it's not dark) so continue counting
WEND

if GPIO.4= 0 then ENCODE ' It really ia dark so carry on and transmit VISITS

'IF GPIO.4= 1 THEN Main '(changed from return) It's not dark after all so carry_on_sleeping_counting

Encode:
E_OUT=1 ' Turn transmitter on

What happens now is when the push button on GPIO.4 is pressed (and held down) After a count of 9 seconds approx (I was expecting a count of two to give half that time) the TX board led lights but still nothing is transmitted.

The program still doesn't seem to get to encode and transmit, frustrating, any other thoughts?

Dave

LEDave
- 5th April 2011, 22:21
Bert

As an aside to the problem, earlier on in the program we have:


Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.

IF GPIO.3= 1 AND GPIO.4= 1 THEN ' Nothing has happened so SLEEP
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No Inputs detected or it's still light so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz indefinatly
@ NOP ' Do nothing for 1st instruction on wake-up
ELSE
'IF GPIO.3=0 THEN GOSUB COUNTS 'Bird detected at box - GOTO LABEL COUNTS
IF GPIO.4=0 THEN DARK 'It's got dark? or just cloudy - GOTO LABEL DARK
ENDIF
GOTO MAIN 'Back to sleep / continue counting

Does this mean that using a WDT and a SLEEP command to save power are kind of mutually exclusive? The SLEEP command turns the PIC off (saving power) then the WDT turns the PIC back on again 4.6seconds later in our case? The above code would keep looping on and off until a button is pressed or the 3v cell goes flat?

Dave

LEDave
- 8th April 2011, 00:45
Have spent several interesting but largely fruitless hours trying to make some progress with the program.

However if I jump passed the COUNTER / WDT routine the TX & RX work fine which is good to know.

Here's the code for it:


COUNTER=0 ' clear before entry
WHILE COUNTER <= 2 ' 4.608sec Loop time (Loop for 30 mins = 781)
INTCON.0 = 0 ' Clear int on change flag
@ SLEEP
@ NOP
CLEARWDT
COUNTER=COUNTER+1

One thought does occur to me though, at the start of the program the PIC is placed into SLEEP mode, only to be woken on INTERRUPT.

Code below.


IF GPIO.3= 1 AND GPIO.4= 1 THEN ' Nothing has happened so SLEEP
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No Inputs detected or it's still light so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz indefinatly
@ NOP ' Do nothing for 1st instruction on wake-up
CLEARWDT
ELSE
'IF GPIO.3=0 THEN GOSUB COUNTS 'Bird detected at box - GOTO LABEL COUNTS
IF GPIO.4=0 THEN encode 'DARK 'Encode 'DARK 'It's got dark? or just cloudy - GOTO LABEL DARK

However, GPIO.4 must be pressed and held down (simulating night time) which causes the wake up from SLEEP interrupt, the program then moves down to the COUNTER / WDT loop. I think I might have found a problem here though. For the COUNTER / WDT loop to work and give a 4.6sec test delay the PIC must go into SLEEP mode, if GPIO.4 is continually held down simulating night time and hence causing an INTERRUPT from SLEEP (continually, even resetting the interrupt won't help as button continually pressed) then my thinking says the COUNTER /WDT loop will never work because the PIC is always being woken up.

A bit garbled I know, sorry, but am I onto something.

Dave

LEDave
- 11th May 2011, 19:43
I'm having a problem getting the rfpic transmitter to Tx when I want it to. I've set up an ON INTERRUPT with DISABLE - RESUME - ENABLE and have the INTCON & IOC set at:


INTCON = %00001000 & IOC = %00011000

What happens is, when buttons GPIO3/4 are pressed (and released)the RFEN led after a 5sec delay briefly flashes but no data is sent. If GPIO.3/4 are pressed and held down after 10 secs the RFEN led lights up the five seconds later (button still held down) data is Tx'd, the button is then released and five seconds later the RFEN led goes out.

What I'd like is for the buttons GPIO.3/4 to be pressed, ON INTERRUPT runs then five seconds later after the delay loop the data is Tx'd. Does anyone have any idea on what's going wrong?


@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF

DEFINE OSC 4
DEFINE OSCCAL_1K 1
DEFINE NO_CLRWDT 1

SYMBOL D_OUT = GPIO.2 ' RF serial data output
SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output

ON INTERRUPT GOTO Delay

DAT_OUT VAR BYTE ' Holds 8-bit data byte
CHK_SUM VAR BYTE ' Holds calculated checksum of outbound data
VISITS VAR WORD ' Loop variable (300 for test)
I VAR word ' Delay Loop Count value
BAUD VAR WORD ' Holds baud rate

' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte
N4800 CON 188 ' 4800 bps
N2400 CON 16780 ' 2400 bps
GUARD CON 5 ' 5mS guard time pause


' hardware init
GPIO = 0 ' Everything off on boot
' GPIO.2=data out, GPIO.5=RF enable, GPIO.3,4 = Bird_visit_count / It's dark..maybe
TRISIO = %00011011 '
ANSEL = 0 ' Disable A/D
INTCON = %00001000 ' Enable port change wakeup from sleep
WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)
IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4
VRCON = 0 ' Disable internal Vref
CMCON = 7 ' Disable comparators
OPTION_REG = 0 ' Pull-ups on

D_OUT = 0 ' Idles low for inverted serial output
E_OUT = 0 ' Enable for RF transmitter=0 (transmiter off)
BAUD = N2400 ' Set baud rate here

Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.
IF GPIO.3= 1 AND GPIO.4= 1 THEN ' Nothing has happened so SLEEP
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No Inputs detected or it's still light so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz indefinatly / Waiting for IOC
@ NOP
'ON INTERRUPT starts / returns here with Button_press: goes to LABEL - "DELAY":

ENDIF
Encode:
E_OUT=1 ' Turn transmitter on
pauseus 25 ' Let transmitter settle
DAT_OUT = %10101001

'Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
'LET VISITS = VISITS / 2 'Just VISITS too not from the box
LET VISITS = 300 'Test data number
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,VISITS.high byte,VISITS.lowbyte]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.
GOTO Main

disable

Delay:
FOR I = 1 TO 5
PAUSe 1000
nEXT I
INTCON.0 = 0
resume : enable
goto Main


Dave

Archangel
- 12th May 2011, 04:52
I think change this to the number that represents
the mode referenced by this. I "think" baud is
1 byte trying to hold 5 byte ASCII word.



BAUD = N2400 ' Set baud rate here
I am not home right now, so I cannot check, does
this PIC have interrupts? On the pins you want them?
Finally "On Interrupt" is like asking you teen to
clean his room, he will, someday.
Use DT_INTS for fast reliable interrupts, maybe will not fit a 675.

LEDave
- 12th May 2011, 10:07
5485


does
this PIC have interrupts? On the pins you want them?


Hi Joe, from the data sheet (pasted above) so yes IOC on pins I need.

I've changed BAUD to:


BAUD = 16780 ' Set baud rate here

Program does same as before though - Also if @SLEEP is commented out as
mackrackit suggested earlier, the rfpic transmits pretty much transmits on button press.


Use DT_INTS for fast reliable interrupts, maybe will not fit a 675.

I'll have a look into DT_INTS later today, thanks for the pointer.

PS: Sorry for pasting Data sheet info into the thread instead of as an attachment, not sure what I did wrong there.

Dave

mackrackit
- 12th May 2011, 13:13
Yes, I told you to use DISABLE-ENABLE-RESUME... I thought you were playing with ONINTERUPPT.

Looks like you are still using Bruce's code as a base, so lets go back to it and modify it some.

But first you may want to try Bruce's code as he wrote it to make sure your hardware is working correctly.



'************************************************* ***************
'* Name : rfPIC_TX.BAS *
'* Author : B. Reynolds *
'* Notice : Copyright (c) 2007 Reynolds Electronics *
'* : All Rights Reserved *
'* Date : 10/09/2007 *
'* Version : 1.0 *
'* Notes : 2-BIT Encoder for remote control with the *
'* : rfPIC12F675 on Microchip rfPIC demo board *
'************************************************* ***************
@ DEVICE PIC12F675,MCLR_OFF,INTRC_OSC_NOCLKOUT,WDT_OFF,BOD_ OFF
@ DEVICE PWRT_ON,PROTECT_OFF

' With rfRXD0420 module installed in PICkit 1 board;
' SW1 toggles LED D6 on PICkit 1 board
' SW2 toggles LED D7 on PICkit 1 board
DEFINE OSC 4
DEFINE NO_CLRWDT 1
DEFINE OSCCAL_1K 1

SYMBOL D_OUT = GPIO.2 ' RF serial data output
SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output

DAT_OUT VAR BYTE ' Holds 8-bit data byte
LOOPS VAR BYTE ' Loop var
CHK_SUM VAR BYTE ' Holds calculated checksum of outbound data
BAUD VAR WORD ' Holds baud rate

' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte
N4800 CON 188 ' 4800 bps
N2400 CON 16780 ' 2400 bps
GUARD CON 5 ' 5mS guard time pause

' hardware init
GPIO = 0 ' Everything off on boot
' GPIO.2=data out, GPIO.5=RF enable, GPIO.3,4=SW1/SW2 switch inputs (rfPIC board)
TRISIO = %00011011 '
ANSEL = 0 ' Disable A/D
INTCON = %00001000 ' Enable port change wakeup from sleep
WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)
IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4
VRCON = 0 ' Disable internal Vref
CMCON = 7 ' Disable comparators
OPTION_REG = 0 ' Pull-ups on

D_OUT = 0 ' Idles low for inverted serial output
E_OUT = 0 ' Enable for RF transmitter=0 (transmiter off)
BAUD = N2400 ' Set baud rate here

Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.
IF (GPIO.3=1) AND (GPIO.4=1) THEN ' pins will be 0 only when buttons are pressed
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No buttons down, so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz
@ NOP ' Do nothing for 1st instruction on wake-up
ENDIF
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

' Button pressed (or being held down), so keep going
' Here is where you want to put the 5 second loop
Delay:
FOR I = 1 TO 5
PAUSe 1000
NEXT I
'Then check the buttons again
IF (GPIO.3=1) AND (GPIO.4=1) THEN

'Look for ENDIF near the end.
'If button are still pressed then it goes to ENCODE
'If not, go back to MAIN and the INTERRUPT ON CHANGE will be reset
Encode:
' Only DAT_OUT bits 1 and 2 are used. We add a few 1's in bit
' positions 0,3,5,7 to balance out the data packet being sent.
DAT_OUT = %10101001
' Get data on button inputs & invert 0's to 1's
DAT_OUT.0[1]=~GPIO.3
DAT_OUT.0[2]=~GPIO.4
INTCON.0 = 0 ' Clear int on change flag

' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.

ENDIF
GOTO Main

END

LEDave
- 12th May 2011, 20:05
Hi mackrackit


Yes, I told you to use DISABLE-ENABLE-RESUME... I thought you were playing with ONINTERUPPT.

I did and I am still hoping to get it working: Post #893 above has ON INTERRUPT -DISABLE-ENABLE-RESUME in the code.

Thanks for the TX program, I had to change:


@DEVICEPIC12F675,MCLR_OFF,INTRC_OSC_NOCLKOUT,WDT_O FF,BOD_OFF
@ DEVICE PWRT_ON,PROTECT_OFF

To:


@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _BODEN_OFF & _PWRTE_ON

To make the program compile, are the above changes ok?

So what happened when I ran it? Well the RFEN led lit for five seconds immediately either button was pressed but nothing was transmitted. I then commented out the delay loop, the RFEN led lit when buttons pressed then went off when button released - still no data sent.

I see where you're coming from with the IF - THEN with the program then going onto the ENDIF statement.

I made a small change adding:


IF (GPIO.3=1) AND (GPIO.4=1) THEN goto Main
if (GPIO.3=0) OR (GPIO.4=0) THEN 'Look for ENDIF

The result was the RFEN led lit for five seconds immediately either button was pressed but nothing was transmitted (as before) however, when the delay loop was commented out data was trnsmitted.

It seems to me that the delay loop is killing the data transfer. What do you think?


But first you may want to try Bruce's code as he wrote it to make sure your hardware is working correctly.

I've saved Bruce's original code as Tx - Rx Master, works a treat.

Dave

LEDave
- 13th May 2011, 00:43
A breakthrough, I think....

I moved the delay loop to run right after the IOC from @SLEEP. So what happens now is if GPIO.3/4 are held down, after 5sec delay data is Tx'd. If GPIO.3/4 are pressed and released within 5secs PIC goes back to @SLEEP.

mackrackit, idea why moving the delay loop 'made a difference' to my mind it should have worked where you put it too.


IF (GPIO.3=1) AND (GPIO.4=1) THEN ' pins will be 0 only when buttons are pressed
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No buttons down, so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz
@ NOP ' Do nothing for 1st instruction on wake-up
FOR I = 1 TO 5
PAUSe 1000
NEXT I
ENDIF
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

'Then check the buttons again
IF (GPIO.3=1) AND (GPIO.4=1) THEN Main 'Button not pressed or pressed then released
if (GPIO.3=0) OR (GPIO.4=0) THEN 'Carry on to ENDIF & Tx DATA


Dave

Archangel
- 13th May 2011, 01:20
5485



Hi Joe, from the data sheet (pasted above) so yes IOC on pins I need.

I've changed BAUD to:


BAUD = 16780 ' Set baud rate hereProgram does same as before though - Also if @SLEEP is commented out as
mackrackit suggested earlier, the rfpic transmits pretty much transmits on button press.



I'll have a look into DT_INTS later today, thanks for the pointer.

PS: Sorry for pasting Data sheet info into the thread instead of as an attachment, not sure what I did wrong there.

Dave
OK, now at home I see why it would work Baud = n2400, because n2400 is set as a symbol in modedefs.bas as 4 (mode 4 ) so its a variable aliasing a constant. Explains Why it Should work. 16780 is a serout2 mode . . . does it work with serout ?
Edit:
Oh My Bad, you are using serout2.

mackrackit
- 14th May 2011, 10:38
mackrackit, idea why moving the delay loop 'made a difference' to my mind it should have worked where you put it too.
I am really missing something or there is something else in your code...
I do not see why you had to move the delay. Your way the delay should be jumped over when a button is pressed...

LEDave
- 14th May 2011, 19:58
Made a mistake, please ignore this post,Dave.

LEDave
- 14th May 2011, 20:11
I am really missing something or there is something else in your code...

Hi mackrackit

I reloaded your code and the rfpic worked exactly as before, namely:

The RFEN led lit for five seconds immediately either button was pressed but nothing was transmitted.


I do not see why you had to move the delay. Your way the delay should be jumped over when a button is pressed...

Mm, I thought (hoped) the PIC would go to SLEEP then IOC would wake it and the program would run from where it went to SLEEP, so the next thing it would do was run the delay loop...? ON INTERRUPT is on hold right now until we get the delay loop to work with the rfpic tx-ing after the delay. I'm not using ON INTERRUPT RIGHT now.


IF (GPIO.3=1) AND (GPIO.4=1) THEN ' pins will be 0 only when buttons are pressed
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No buttons down, so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz
@ NOP ' Do nothing for 1st instruction on wake-up
FOR I = 1 TO 5
PAUSe 1000
NEXT I
ENDIF
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

'Then check the buttons again
IF (GPIO.3=1) AND (GPIO.4=1) THEN Main 'Button not pressed or pressed then released
if (GPIO.3=0) OR (GPIO.4=0) THEN 'Carry on to ENDIF & Tx DATA

Dave

cncmachineguy
- 14th May 2011, 21:05
Jumping in again, possibly completely off base here. But, is there any kind of max time between when you enable the tx, and when you send it data? Because all I see different about moving the delay loop is then enable is moved after it.

As a side note, why not change the for loop to something much bigger like 1 to 250, then make the pause time of 20. This won't help the current problem, but when you are back to on interrupt you will not be trapped in the pause for near as long.

LEDave
- 14th May 2011, 23:33
Jumping in again, possibly completely off base here. But, is there any kind of max time between when you enable the tx, and when you send it data? Because all I see different about moving the delay loop is then enable is moved after it.

Hi cncmachineguy, I suspect timing has a lot to do with it (although I don't kow enough to say or point to why).

Plenty of head scratching going on here.


As a side note, why not change the for loop to something much bigger like 1 to 250, then make the pause time of 20. This won't help the current problem, but when you are back to on interrupt you will not be trapped in the pause for near as long..

Yes, pauses for too long are bad news for what I'm aiming at with this project.

Dave

mackrackit
- 15th May 2011, 00:42
In my code try moving

E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

to the beginning of the
Encode:
block...

Search this document for "RFEN"..
http://ww1.microchip.com/downloads/en/devicedoc/70091a.pdf

LEDave
- 15th May 2011, 02:01
I moved the code.

What happens is:

1/ If a button is pressed and released RFEN briefly flashes after the 5sec delay (no data is Tx'd).

2/ If a button is continually pressed, nothing happens at all (RFEN doesn't light / no data is Tx'd.

Dave

mackrackit
- 15th May 2011, 02:31
How is the voltage on the power supply/battery?

I hope Bruce stops in and sees this as I am lost...

LEDave
- 15th May 2011, 02:59
How is the voltage on the power supply/battery?

I'm using a power supply set at 4.66v.

For some reason my attachments are appearing here 'inline' rather than at the page bottom, sorry.

The comment about dataask going high caught my eye. Maybe our timing is off a touch (not sure if or why) with the RFEN coming on and us missing data-ask going high (there is no technical reason why anything I've just typed is remotely true) Just my gut....aka....Agent Gibbs style...!

5503

Dave

cncmachineguy
- 15th May 2011, 03:32
Sorry guys, I will have to just keep following. I'm stumpted.

Demon
- 15th May 2011, 03:45
Can you post your entire program as it stands now?

(There's no way my feeble mind can remember all changes through a 23 page thread.)

LEDave
- 15th May 2011, 09:43
Two versions to look at really Demon. I've posted two, it might help you see 'something' because although very similar, what they both do is subtley different things.

The first one does this on button presses:

1/ If a button is pressed and released RFEN briefly flashes after the 5sec delay (no data is Tx'd).

2/ If a button is continually pressed, nothing happens at all (RFEN doesn't light / no data is Tx'd.



@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _BODEN_OFF & _PWRTE_ON

' With rfRXD0420 module installed in PICkit 1 board;
' SW1 toggles LED D6 on PICkit 1 board
' SW2 toggles LED D7 on PICkit 1 board
DEFINE OSC 4
DEFINE NO_CLRWDT 1
DEFINE OSCCAL_1K 1

SYMBOL D_OUT = GPIO.2 ' RF serial data output
SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output

DAT_OUT VAR BYTE ' Holds 8-bit data byte
LOOPS VAR BYTE ' Loop var
CHK_SUM VAR BYTE ' Holds calculated checksum of outbound data
BAUD VAR WORD ' Holds baud rate
I VAR BYTE

' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte
N4800 CON 188 ' 4800 bps
N2400 CON 16780 ' 2400 bps
GUARD CON 5 ' 5mS guard time pause

' hardware init
GPIO = 0 ' Everything off on boot
' GPIO.2=data out, GPIO.5=RF enable, GPIO.3,4=SW1/SW2 switch inputs (rfPIC board)
TRISIO = %00011011 '
ANSEL = 0 ' Disable A/D
INTCON = %00001000 ' Enable port change wakeup from sleep
WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)
IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4
VRCON = 0 ' Disable internal Vref
CMCON = 7 ' Disable comparators
OPTION_REG = 0 ' Pull-ups on

D_OUT = 0 ' Idles low for inverted serial output
E_OUT = 0 ' Enable for RF transmitter=0 (transmiter off)
BAUD = N2400 ' Set baud rate here

Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.
IF (GPIO.3=1) AND (GPIO.4=1) THEN ' pins will be 0 only when buttons are pressed
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No buttons down, so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz
@ NOP ' Do nothing for 1st instruction on wake-up
ENDIF
' E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
' PAUSEUS 25 ' Allow RF stage to stabilize

' Button pressed (or being held down), so keep going
' Here is where you want to put the 5 second loop
Delay:
FOR I = 1 TO 5
PAUSe 1000
NEXT I
'Then check the buttons again
IF (GPIO.3=1) AND (GPIO.4=1) THEN
'Look for ENDIF near the end.
'If button are still pressed then it goes to ENCODE
'If not, go back to MAIN and the INTERRUPT ON CHANGE will be reset
Encode:
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize
' Only DAT_OUT bits 1 and 2 are used. We add a few 1's in bit
' positions 0,3,5,7 to balance out the data packet being sent.
DAT_OUT = %10101001
' Get data on button inputs & invert 0's to 1's
DAT_OUT.0[1]=~GPIO.3
DAT_OUT.0[2]=~GPIO.4
INTCON.0 = 0 ' Clear int on change flag

' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.
ENDIF
GOTO Main

END

This one does this:

1/ Tx's the data after the button is continually held down for 5secs.

2/ The RFEN led briefly flashes (after 5secs) if either button is pressed and released.


@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _BODEN_OFF & _PWRTE_ON

' With rfRXD0420 module installed in PICkit 1 board;
' SW1 toggles LED D6 on PICkit 1 board
' SW2 toggles LED D7 on PICkit 1 board
DEFINE OSC 4
DEFINE NO_CLRWDT 1
DEFINE OSCCAL_1K 1

' ON INTERRUPT goto Delay

SYMBOL D_OUT = GPIO.2 ' RF serial data output
SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output

DAT_OUT VAR BYTE ' Holds 8-bit data byte
LOOPS VAR BYTE ' Loop var
CHK_SUM VAR BYTE ' Holds calculated checksum of outbound data
BAUD VAR WORD ' Holds baud rate
I VAR BYTE

' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte
N4800 CON 188 ' 4800 bps
N2400 CON 16780 ' 2400 bps
GUARD CON 5 ' 5mS guard time pause

' hardware init
GPIO = 0 ' Everything off on boot
' GPIO.2=data out, GPIO.5=RF enable, GPIO.3,4=SW1/SW2 switch inputs (rfPIC board)
TRISIO = %00011011 '
ANSEL = 0 ' Disable A/D
INTCON = %00001000 ' Enable port change wakeup from sleep
WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)
IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4
VRCON = 0 ' Disable internal Vref
CMCON = 7 ' Disable comparators
OPTION_REG = 0 ' Pull-ups on

D_OUT = 0 ' Idles low for inverted serial output
E_OUT = 0 ' Enable for RF transmitter=0 (transmiter off)
BAUD = N2400 ' Set baud rate here

Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.

IF (GPIO.3=1) AND (GPIO.4=1) THEN ' pins will be 0 only when buttons are pressed
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No buttons down, so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz
@ NOP ' Do nothing for 1st instruction on wake-up
FOR I = 1 TO 5
PAUSe 1000
NEXT I
ENDIF

'Then check the buttons again

IF (GPIO.3=1) AND (GPIO.4=1) THEN Encode 'Button pressed & released But carry on)
if (GPIO.3=0) OR (GPIO.4=0) THEN 'Carry on to ENDIF & Tx DATA

'Look for ENDIF near the end.
'If button are still pressed then it goes to ENCODE
'If not, go back to MAIN and the INTERRUPT ON CHANGE will be reset
Encode:
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize
' Only DAT_OUT bits 1 and 2 are used. We add a few 1's in bit
' positions 0,3,5,7 to balance out the data packet being sent.
DAT_OUT = %10101001
' Get data on button inputs & invert 0's to 1's
DAT_OUT.0[1]=~GPIO.3
DAT_OUT.0[2]=~GPIO.4
INTCON.0 = 0 ' Clear int on change flag

' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.

ENDIF
GOTO Main

END

Dave

Demon
- 15th May 2011, 21:05
I started by looking at your first code:



'Then check the buttons again
IF (GPIO.3=1) AND (GPIO.4=1) THEN
'Look for ENDIF near the end.
'If button are still pressed then it goes to ENCODE
'If not, go back to MAIN and the INTERRUPT ON CHANGE will be reset
Encode:
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize
' Only DAT_OUT bits 1 and 2 are used. We add a few 1's in bit
' positions 0,3,5,7 to balance out the data packet being sent.
DAT_OUT = %10101001
' Get data on button inputs & invert 0's to 1's
DAT_OUT.0[1]=~GPIO.3
DAT_OUT.0[2]=~GPIO.4
INTCON.0 = 0 ' Clear int on change flag

' Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.
ENDIF
GOTO Main


If GPIO.3 and GPIO.4 are both 1, then neither are being pressed when pull-up resistors are used.




'If button are still pressed then it goes to ENCODE
'If not, go back to MAIN and the INTERRUPT ON CHANGE will be reset


I read these comments backwards to what the code does.


Personally, the technique of using 1 for OFF and 0 for ON is extremely confusing; it makes trying to follow your code extremely difficult. I always use pull-down resistors and 0=OFF / 1=ON 'cause that's how binary works as well as power switches.

EDIT: Unless it's a requirement for Sleep mode to have current ON, and the interruption signals Wake.

Otherwise, if power consumption is an issue, I'd keep the line OFF, saving power, and only applying a bit of current to Wake.

LEDave
- 15th May 2011, 21:37
Hi mackrackit / All

In Bruce's oringinal code, the rfpic (if no buttons are pressed) goes to SLEEP until a button is pressed then Encodes & Tx's straight away.

It seemed to me the data Tx is dependant on a button press occuring and staying pressed until the data is Tx'd. If a button is pressed then released the RFEN led flashes but no data is ever sent, hence our delay loop problem, the button is pressed then released by the time the loop has run the button press is history. The the only time data has ever Tx'd is when the button is actually pressed when the code gets to 'Transmit'.

I added LOW GPIO.4 to simulate a button press (staying pressed) result: The rfpic Tx'd no problem after the delay loop had run.

We now have a IOC that wakes up from sleep, then runs a delay loop, then Tx's the data. We've cracked it you cry.....hoorah! Well almost, problem is the rfpic locks into Tx mode (GPIO.4 is always low - Button is never released if you like).

Figure a way of GPIO.4 back to 'normal' and we're there, any thoughts. Bear in mind though that GPIO.4 must be 'low' to make the rfpic Tx.

Any ideas....?


Transmit:
LOW GPIO.4
SEROUT2 D_OUT,BAUD,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.


Dave

LEDave
- 15th May 2011, 21:48
Hi Demon

I hear what you're saying. By the time this project is finished a lot of changes will have been made to the set-up.

This is my first excursion into RF, with Tx - Rx programs that Bruce kindly posted up. Right now it's a learning curve for me.

Dave

LEDave
- 16th May 2011, 23:44
I think I've sent everyone on a wild Goose chase (sorry):o.

Mackrackit's Tx code was working fine all along.

I now think It's the Rx program that holds the key. The reason I think this is becasue Bruce's Rx program (as I understand it) looks to reset if no data recieved within 65ms of button press ( that's why the data only ever Tx'd with a button actually pressed). Any timing loop throws out the 65ms data arrival, hence no flahing led.

I commented out a section of the Rx program and although not working perfectly, the Rx led now flashes after the time delay and data is sent.

What do we think? Am I on to something here?

Again apologies for the curved ball.

Dave

cncmachineguy
- 17th May 2011, 00:25
Well thats good to know, Thanks Dave!! So does that me the Tx side is done? Do we get to see the Rx side to chew on for a bit?

LEDave
- 17th May 2011, 00:56
Well thats good to know, Thanks Dave!! So does that me the Tx side is done?

Hi Bert

Well no the Tx side still has work to be done. The delay loop problem has / had to be overcome to get the project code to do what I want it to. The GPIO.3 / 4 pins will need to be set as as Demon posted earlier, namely:


I always use pull-down resistors and 0=OFF / 1=ON 'cause that's how binary works as well as power switches.


Do we get to see the Rx side to chew on for a bit?

I'll tidy it up and post it tomorrow. The big thing for me is that Mackrackit agree's I'm on the right track with my thinking regards Rx being the problem not the Tx side.

Dave

mackrackit
- 17th May 2011, 01:02
Mackrackit's Tx code was working fine all along.

But the other code (Bruce's) worked when my mod did not appear to ???

Yup, we need to see both ends.


But it does sound like you are on to something....

LEDave
- 17th May 2011, 13:53
But the other code (Bruce's) worked when my mod did not appear to ???

It did / does. Bruce's code for the Tx - Rx on button press works a treat, it never misses a beat. The problem appears when we try and add in a time delay loop.

Here's Bruce's original Rx code (a button press on the transmitter = immediate led flash on Rx board).


'************************************************* ***************
'* Name : rfPIC_RX.BAS *
'* Author : B. Reynolds *
'* Notice : Copyright (c) 2007 Reynolds Electronics *
'* : All Rights Reserved *
'* Date : 10/09/2007 *
'* Version : 1.0 (Momentary decoder version) *
'* Notes : 2-Bit decoder for Microchip RF dev system *
'* : with rfRXD0420 module installed in PICkit 1 board *
'* PIC : PIC16F684 Originally PIC16F676!!! *
'************************************************* ***************
@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _PWRTE_ON
DEFINE OSC 4
DEFINE NO_CLRWDT 1 ' Watchdog timer is disabled, so we don't need to reset it
DEFINE INTHAND RESET_VT ' Interrupt on Timer1 overflow to reset outputs in 65.5mS
' if no serial data received in this time period
SYMBOL D_IN = PORTC.1 ' data input pin
SYMBOL TMR1IF = PIR1.0 ' Timer1 overflow interrupt flag (reset in int handler)
SYMBOL TMR1IE = PIE1.0 ' Timer1 interrupt enable bit

'Variables for saving state in interrupt handler
wsave VAR BYTE $5F system ' Saves W
ssave VAR BYTE bank0 system ' Saves STATUS
psave VAR BYTE bank0 system ' Saves PCLATH
fsave VAR BYTE bank0 system ' Saves FSR

' Working variables
MATCH VAR BYTE bank0 system ' Match variable
DAT_OUTB VAR BYTE ' Holds decoded data for output
DAT_IN1 VAR BYTE ' 1st Data byte
DAT_IN2 VAR BYTE ' 2nd Data byte for verify
CHK_SUM VAR BYTE ' Holds checksum received
CheckSum VAR BYTE ' Computed checksum of all bytes received
LOOPS VAR BYTE ' Loop var

' Constants
Synch CON "~" ' 01111110 synch byte
N2400 CON 16780 ' 2400 bps inverted
N4800 CON 188 ' 4800 bps inverted

' hardware init
PORTA = 0
TRISA = %00111001 ' RA1 and RA2 are LED outputs
PORTC = 0 ' Clear outputs on power-up
TRISC = %00111110 ' RC1 = RF input
IOC = 0 ' Interrupt on change disabled
VRCON = 0 ' Comparator Vref disabled
CMCON0 = 7 ' Disable comparators
ANSEL = 0 ' disable A/D
OPTION_REG = 128 ' Pull-ups off

' Setup Timer1 for resets after ~65.5mS
T1CON = %00000000 ' Internal clock, 1:1 prescale, Timer1 off for now
TMR1L = 0
TMR1H = 0 ' Timer1 low & high bytes cleared
TMR1IF = 0 ' Clear Timer1 overflow flag before enabling interrupt
TMR1IE = 1 ' Enable Timer1 overflow interrupt
INTCON = %11000000 ' Global & peripheral ints enabled
MATCH = 0 ' Clear match count
GOTO MAIN ' Jump over int handler

ASM ; Timer1 overflow interrupt resets outputs when no valid key press
; is detected within ~65mS
RESET_VT
movwf wsave ; Save W
swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
movf PCLATH, W ; Move PCLATH to W
movwf psave ; Save PCLATH
movf FSR, W ; Move FSR to W
movwf fsave ; Save FSR

; Do interrupt stuff here
bcf T1CON,TMR1ON ; Stop Timer1
clrf TMR1L ; Clear low byte
clrf TMR1H ; Clear high byte
bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag bit
clrf PORTA ; Clear outputs on button release
clrf MATCH ; Clear match variable

; Restore FSR, PCLATH, STATUS and W registers
movf fsave, W ; retrieve FSR value
movwf FSR ; Restore it to FSR
movf psave, W ; Retrieve PCLATH value
movwf PCLATH ; Restore it to PCLATH
swapf ssave, W ; Get swapped STATUS value (swap to avoid changing STATUS)
movwf STATUS ; Restore it to STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it to W (swap to avoid changing STATUS)
bsf T1CON,TMR1ON ; Re-enable Timer1 before exiting interrupt handler
retfie ; Return from the interrupt
ENDASM

MAIN:

' Fire up Timer1 before entry to serial input routine
T1CON.0 = 1

' at 4MHz Timer1 overflows in 65536 * 1uS (~65.5mS) if no Synch byte
' and serial data arrive on time. SERIN2 timeout & label options
' are useless with a noisy RF receiver output - as noise continually
' resets the timeout period causing it to hang forever.

' Wait for Synch byte, then get new inbound data & checksum
SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM]

T1CON.0 = 0 ' Stop Timer1 once we've received data
TMR1L = 0 ' Clear low byte
TMR1H = 0 ' Clear high byte

' / **** Begin data validation **** /

' Calculate checksum by adding 2 data bytes together
CheckSum = DAT_IN1 + DAT_IN2

' Test new checksum against one received in CHK_SUM
IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return

' Test data bytes for match
IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return

MATCH = MATCH + 1 ' We have a match so increment match count
IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good
GOTO Main ' Else do it all over

' Everything looking good - so place new data on outputs
DECODE:
' Place decoded values on port pins..
PORTA = DAT_IN1 & %00000110
DAT_IN1 = !DAT_IN2 ' Destroy the match
MATCH = 0
GOTO MAIN

END

And here's the 'chopped down' version which doesn't Rx on every Tx but DOES Rx after the timing loop on the Tx has run.


@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _PWRTE_ON
DEFINE OSC 4
DEFINE NO_CLRWDT 1 ' Watchdog timer is disabled, so we don't need to reset it

SYMBOL D_IN = PORTC.1 ' data input pin

' Working variables
MATCH VAR BYTE bank0 system ' Match variable
DAT_OUTB VAR BYTE ' Holds decoded data for output
DAT_IN1 VAR BYTE ' 1st Data byte
DAT_IN2 VAR BYTE ' 2nd Data byte for verify
CHK_SUM VAR BYTE ' Holds checksum received
CheckSum VAR BYTE ' Computed checksum of all bytes received
LOOPS VAR BYTE ' Loop var
VISITS var word ' Test BYTE with a value of 3 - DT
X VAR BYTE ' Loop counter value Byte - DT
Total var byte

' Constants
Synch CON "~" ' 01111110 synch byte
N2400 CON 16780 ' 2400 bps inverted
N4800 CON 188 ' 4800 bps inverted

' hardware init
PORTA = 0
TRISA = %00111001 ' RA1 and RA2 are LED outputs
PORTC = 0 ' Clear outputs on power-up
TRISC = %00101110 ' RC1 = RF input
IOC = 0 ' Interrupt on change disabled
VRCON = 0 ' Comparator Vref disabled
CMCON0 = 7 ' Disable comparators
ANSEL = 0 ' disable A/D
OPTION_REG = 128 ' Pull-ups off


INTCON = %11000000 ' Global & peripheral ints enabled
MATCH = 0 ' Clear match count
GOTO MAIN ' Jump over int handler

MAIN:

' Wait for Synch byte, then get new inbound data & checksum
SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM,VISITS.HIGHBYT E,VISITS.LOWBYTE]

' / **** Begin data validation **** /

' Calculate checksum by adding 2 data bytes together
CheckSum = DAT_IN1 + DAT_IN2

' Test new checksum against one received in CHK_SUM
IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return

' Test data bytes for match
IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return

' MATCH = MATCH + 1 ' We have a match so increment match count
' IF MATCH = 2 THEN DECODE ' Everything matched twice, we're good
' GOTO Main ' Else do it all over

' Everything looking good - so place new data on outputs
DECODE:

'DAT_IN1 = !DAT_IN2 ' Destroy the match
' MATCH = 0

IF VISITS = 300 THEN LED
GOTO MAIN

lED:

for X = 1 to 3 'Test=7 or 600
HIGH PORTA.1
PAUSE 500
LOW PORTA.1
pause 500
next X
GOTO MAIN


END


Dave

Demon
- 17th May 2011, 15:40
I use config fuse WTD_OFF and never had to use this:



DEFINE NO_CLRWDT 1 ' Watchdog timer is disabled, so we don't need to reset it


(still looking over rest of code)

cncmachineguy
- 17th May 2011, 16:11
Without the define, PBP will sprinkle CLTWDT through out your code. The Config tells uP not to use it, the DEFINE tells PBP not to.

Demon
- 17th May 2011, 16:32
Without the define, PBP will sprinkle CLTWDT through out your code. ...

I cannot Find CLTWDT in the ASM file of my latest project?

So I went through older larger programs in code size was an issue. None of the ASM has CLTWDT either.

LEDave
- 17th May 2011, 18:12
Just had a breakthrough with the project:)

Having modified Bruce's code to make the timing loop run & transmit. Tx 'consistancy' was a problem. The data was only recieved about 3 in 5 times. So reading the Manual, I added PACE to the program with a 5ms delay, result the data now gets Tx'd & Rx'd everytime with the delay loop.....Whoopee....!


SEROUT2 D_OUT,BAUD,PACE,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,VISITS.high byte,VISITS.lowbyte]

Mega_Chuffed tonight.

Dave

mackrackit
- 17th May 2011, 18:52
COOL :D

Can you post the complete code as is? Just to keep everything/everyone UpToDate...

Demon
- 17th May 2011, 18:55
Just had a breakthrough with the project:)
...

Good news!


About the checksum:


SEROUT2 D_OUT,BAUD,PACE,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,VISITS.high byte,VISITS.lowbyte]

I always thought the idea behind checksum was to confirm that a data transfer had completed successfully. As it stands, you are checking data from the front of the stream only. I would put the CHKSUM at the end of your data stream, that way you are certain you have received everything.

It might not be necessary with the way PBP processes Serout commands, but this is from old programming habits in a business environment (you want to be sure everything made it through).



SEROUT2 D_OUT,BAUD,PACE,[PreAmble,Synch,DAT_OUT,DAT_OUT,VISITS.highbyte,VIS ITS.lowbyte,CHK_SUM]


(unless the location of CHKSUM in SEROUT is pre-determined by hardware/software)

Demon
- 17th May 2011, 19:02
...
I added PACE to the program with a 5ms delay, result the data now gets Tx'd & Rx'd everytime with the delay loop.....Whoopee....!
...



How did you control the Pace delay?

I'm looking at Serout2 in PBP manual v2.60 (p.155) and only see reference of adding Pace, possibility of 1 to 65,535 ms delay, but no way of controlling delay.

I assume Pace is a word variable that you assigned a value of 5?

LEDave
- 17th May 2011, 21:30
Can you post the complete code as is? Just to keep everything/everyone UpToDate...

Will do mackrackit.


It might not be necessary with the way PBP processes Serout commands, but this is from old programming habits in a business environment (you want to be sure everything made it through).

Hi Demon. I hear what you're saying, makes good sense. I remember Henrik telling me that it didn't matter whether you sent Highbyte or Lowbyte first, your way kind of gives a check / checksum:)


How did you control the Pace delay?

I used:


PACE CON 5

Dave

LEDave
- 17th May 2011, 22:22
Hi mackrackit.

Here's the Tx and Rx code as is stands. The Tx program now transmits a data WORD on button press, not just the button press itself.

Tx:


@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF

DEFINE OSC 4
DEFINE OSCCAL_1K 1
DEFINE NO_CLRWDT 1

SYMBOL D_OUT = GPIO.2 ' RF serial data output
SYMBOL E_OUT = GPIO.5 ' RF transmitter enable output

VISITS VAR word ' Holds total daily bird visits
DAT_OUT VAR BYTE ' Holds 8-bit data byte
DAT_OUT2 VAR BYTE ' Holds 8-bit test byte
LOOPS VAR BYTE ' Loop var
CHK_SUM VAR BYTE ' Holds calculated checksum of outbound data
I VAR word ' Delay loop count
BAUD VAR WORD ' Holds baud rate

' Constants
PreAmble CON $A5 ' 10100101 preamble
Synch CON "~" ' 01111110 synch byte
N4800 CON 188 ' 4800 bps
N2400 CON 16780 ' 2400 bps
GUARD CON 5 ' 5mS guard time pause
PACE CON 5 ' Set CHAR transmission speed

' hardware init
GPIO = 0 ' Everything off on boot
' GPIO.2=data out, GPIO.5=RF enable, GPIO.3,4 = Bird_visit_count / It's dark..maybe
TRISIO = %00011011 '
ANSEL = 0 ' Disable A/D
INTCON = %00001000 ' Enable port change wakeup from sleep
WPU = %00010000 ' pull-up on for GPIO.4 (external pull-up already on GPIO.3)
IOC = %00011000 ' Wakeup on change enabled for GPIO.3,4
VRCON = 0 ' Disable internal Vref
CMCON = 7 ' Disable comparators
OPTION_REG = 0 ' Pull-ups on

D_OUT = 0 ' Idles low for inverted serial output
E_OUT = 0 ' Enable for RF transmitter=0 (transmiter off)
BAUD = N2400 ' Set baud rate here

Main:
' Read port to clear missmatch, if with no buttons pressed, then
' clear int-on-change flag & snooze until wake up on change. This
' conserves battery power on the demo board with 3V coin cell.

IF GPIO.3= 1 AND GPIO.4= 1 THEN ' Nothing has happened so SLEEP
E_OUT=0 ' Disable transmitter
INTCON.0 = 0 ' No Inputs detected or it's still light so clear int on change flag
@ SLEEP ' and start snoozin..zzzzzzzzzzz indefinatly
@ NOP
ENDIF
' E_OUT=1 ' Mackrackit, I moved this to (after delay loop)this to save power as I need a long
'PAUSEUS 25 ' Delay loop 30mins so saves Transmitter power

Delay:
FOR I = 1 TO 2 ' Delay loop 2sec test
PAUSe 1000
NEXT I

IF GPIO.3=1 and GPIO.4=1 THEN 'Button pressed then released..carry on

Encode:
E_OUT=1 ' Enable transmitter (+ lights RFEN LED on demo board)
PAUSEUS 25 ' Allow RF stage to stabilize

DAT_OUT = %10101001
INTCON.0 = 0 ' Clear int on change flag

'Build checksum of 2 data bytes
CHK_SUM = (DAT_OUT * 2)

Transmit:
'LET VISITS = VISITS / 2 'Just VISITS too not from the box
LET VISITS = 300 'Test data number (Bird visits)
SEROUT2 D_OUT,BAUD,PACE,[PreAmble,Synch,DAT_OUT,DAT_OUT,CHK_SUM,VISITS.high byte,VISITS.lowbyte]
PAUSE GUARD ' 5mS guard time gives decoder time to respond,calculate,change,etc.
endif
GOTO Main


END


When the 'Test Data' number arrives at the Rx the code flashes an led three times if DATA is TRUE.

Rx:


@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _PWRTE_ON
DEFINE OSC 4
DEFINE NO_CLRWDT 1 ' Watchdog timer is disabled, so we don't need to reset it

SYMBOL D_IN = PORTC.1 ' data input pin

' Working variables
MATCH VAR BYTE ' Match variable
DAT_OUTB VAR BYTE ' Holds decoded data for output
DAT_IN1 VAR BYTE ' 1st Data byte
DAT_IN2 VAR BYTE ' 2nd Data byte for verify
CHK_SUM VAR BYTE ' Holds checksum received
CheckSum VAR BYTE ' Computed checksum of all bytes received
LOOPS VAR BYTE ' Loop var
VISITS var word ' Test BYTE with a value of 300
X VAR BYTE ' Loop counter value Byte

' Constants
Synch CON "~" ' 01111110 synch byte
N2400 CON 16780 ' 2400 bps inverted
N4800 CON 188 ' 4800 bps inverted

' hardware init
PORTA = 0
TRISA = %00111001 ' RA1 and RA2 are LED outputs
PORTC = 0 ' Clear outputs on power-up
TRISC = %00101110 ' RC1 = RF input
IOC = 0 ' Interrupt on change disabled
VRCON = 0 ' Comparator Vref disabled
CMCON0 = 7 ' Disable comparators
ANSEL = 0 ' disable A/D
OPTION_REG = 128 ' Pull-ups off


INTCON = 0
MATCH = 0 ' Clear match count

MAIN:

' Wait for Synch byte, then get new inbound data & checksum
SERIN2 D_IN,N2400,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM,VISITS.HIGHBYT E,VISITS.LOWBYTE]

' / **** Begin data validation **** /

' Calculate checksum by adding 2 data bytes together
CheckSum = DAT_IN1 + DAT_IN2

' Test new checksum against one received in CHK_SUM
IF CheckSum != CHK_SUM THEN MAIN ' Failed checksum, return

' Test data bytes for match
IF (DAT_IN1) != (DAT_IN2) THEN MAIN ' Failed data comparison, return

MATCH = MATCH + 1 ' We have a match so increment match count
IF MATCH = 1 THEN DECODE ' Everything matched twice, we're good
GOTO Main ' Else do it all over

' Everything looking good - so place new data on outputs
DECODE:
PORTA = DAT_IN1 & DAT_IN2
DAT_IN1 = !DAT_IN2 ' Destroy the match
MATCH = 0

IF VISITS = 300 THEN LED
GOTO MAIN

lED:

for X = 1 to 3 'Blink led 3 times to show data has arrived (correctly)
HIGH PORTA.1
PAUSE 500
LOW PORTA.1
pause 500
next X
GOTO MAIN


END


Still much to do / change but a good day today. I've sent the Tx / Rx into a continual 'Test' loop
hasn't missed a beat so far, really pleased.

As always thanks for everyone's help, input.

Dave

LEDave
- 21st May 2011, 23:00
Really pleased to say the project took a giant leap forward tonight. Have re-written some of the code to work with pull-down resistor now 0v = off, 5v = on.

Tap a wire +5v to GPIO.0 ten times, then touch GPIO.1 once and the Tx Tx's and the Rx board flashes 5 times (simulates five visits to bird box).

Still plenty to do I'm sure but feeling a little like Marconi this evening.:D

Dave