PDA

View Full Version : Newbie has some questions



bartman
- 6th November 2004, 22:17
Hi everyone,

This winter I want to dabble in PIC programming to make a small hobby project that will randomly turn on and off 16 LEDs.

What I want to do is use a 12F629 to drive a 74HCT154 4->16 encoder/decoder that will run the LEDs.

As I understand it, I will want to have 5 outputs from the 12F that I can make either high or low. This doesn't seem to be a problem from what I read of the 12F.

I have a couple issues since this is all new to me. First, I would like to use the PicBasic compiler due to costs. Since I won't be churning out project after project I really don't want to get into the higher cost of the pro version. Reading the command list of the PicBasic I think it should do what I want.

The main stumbling block is the random factor.

Initially my idea was to generate four random numbers which would translate to 0 or 1 to drive the high/low outputs. This seems simple enough, but since the random numbers are not truely random I'd like to add something else to that end.

I did more reading that in order to have a more true random number an outside event would need to happen to seed the random number generator. This could possible be from something like a 555 timer. Did I understand this correclty?

I assume the timer will be producing pulses which the 12F is going to use to create the random number. This is where I get stumped. There should be one more I/O port on the 12F that I could use after setting aside 5 for the multiplexer, but how do I use that input for the random number?

I want to do this with as few external components as possible and even the 555 would need a couple resistors and capacitors (I don't want to use any variable resistors) In actual operation the pseudo-random generator probably would work fine. It's just my desire to make it better that is driving this idea.

Further, regarding the pseudo generator. I don't fully understand what it is generating. Is it 0 or 1 or 1 to x with x being what upper limit?

I haven't purchased anything software yet until I am sure I have a reasonable chance of making this work. It is completely new to me so please gear any answers for the uneducated!

I've decide the actual source code for my idea should be fairly simple if I remember enough of BASIC from back in school many years ago.

Thanks in advance.

Bart

mister_e
- 7th November 2004, 01:58
Hi Batman,
i recently find this article on hardware radom generator bit

http://willware.net:8080/hw-rng.html

there's some interesting theory in. To read fom this generator you maybe able to use serial communication DEBUG statement. Place the result in a variable... maybe do some math to get random result in a range from 0-16 and that's it.

That's in theory. never tested but ... suppose to do something.

bartman
- 7th November 2004, 03:52
Thanks. I checked out the link and while I can say that I have some idea of what they are saying generally it is beyond me.

From what I can gather, though, is that it would have too many problems for me.

Too many components.
Wants 18 volts and I have 5 to offer.
Uses commands that aren't in PicBasic.

I do think I need to read the input (obviously), but what to do with it? A 555 timer could send pulses. Probably something else could to, but that be simpler? Regardless, I don't know what to do with said pulses.

I'm sure my first attempt won't be exactly what I have in mind. A bit of a steep learning curve for me.

Bart

P.S. I picked the 12F629 pic just because it is small. It may not be the best choice. I also am looking at 16F676 to have more I/O options if needed as a way to the end of the random number puzzle. As long as the chip is fairly small I'm interested in suggestions there too.

Melanie
- 7th November 2004, 09:59
The easiest and simplest way to start with a Random Number seed is to employ the services of the User (unbeknown to them of course).

If you have an On/Off BUTTON, then the PIC powers up very quickly when the ON Button is pressed, and starts counting how long the Button remains pressed until the user releases it. Counting from 0-256 continuously with fosc at 4MHz, there's little chance the User would be able to throw the result even if they knew the Random seed was linked to the ON Button.

The component count in this instance is minimal and you have Push-Button On/Off for your device, which is easier and neater to install than a actual change-over switch (also allows you to have software control of Power-Off if needed).

Melanie

bartman
- 7th November 2004, 17:31
Thanks. I did read about this method as well. The project is powered up via a timer (one of those garden light transformers that has been converted to run DC current) and from there it does its job of randomly turning on one of the 16 LEDs. It is for a lighting effect so there is no human intervention and, at least no way I can think of, no way anyone can trigger the event short of adding more components.

Bart

Melanie
- 7th November 2004, 18:26
You've got 16 lights you want to randomly switch.

Chose a PIC with EEPROM. Fill the EEPROM with a random selection of numbers, and you're away. Nobody's ever going to guess you're recycling a 128 or 256 step sequence - just not humanly possible to remember more than 20 or 30 steps - if anybody can, and can do say 50 numbers repeatedly, contact me - there's a Cassino I wanna hit...

Melanie

bartman
- 7th November 2004, 18:48
I'd go for the casino idea... love Vegas!

You are just way beyond my understanding!

Really, though, you are right that no one is going to notice any sequencing as it is happening. I could just use the Random command to end up with the same thing. I just don't like that on start up it will always start with the same thing.

Let me try and describe my project better.

There are 16 LEDs that will always be on EXCEPT for one that will randomly "blink" off then come back on. Repeat with another random LED and go on this way forever.

Using the 74HCT154 multiplexer makes the job of holding the LED's on a blinking just one at a time easy and it requires 5 inputs in different combinations of high and low to do that. Sounds simple enough at this point.

So using RANDOM to come up with 5 combinations of "0" and "1" in itself is simple using > and < to set the pin. The circuit "should" run away happily forever with not much coding at all except that on each start up it starts the same way and would be noticable until some point where the viewer lost track. Sort of like Pi. We can all remember the first few digits then we just sort of don't pay attention after that.

To get away from this problem I thought I should somehow seed the generator with an outside event. Not because it totally can't work any other way, but because it is neat to come up with a solution that my limited knowledge can carry out.

I've been reading the manual for the PicBasic and trying to understand "Free running" 555 timers and how I could make the two work together under PicBasic and some type of PIC controller. Right now it is all somewhat above me.

Thanks.

Bart

Melanie
- 7th November 2004, 19:44
How often does the PIC get turned on? Each evening, or every time the lady of the house strips off to jump in the pool, or... ?

Your 555 is total overkill.

bartman
- 7th November 2004, 19:49
Each evening after dark.

Bart

Melanie
- 7th November 2004, 20:05
OK, so lets assume you fill all your EEPROM starting from location 1 to the end (let's pretend its address 127) with a Random sequence of Numbers from 1 to 16... EEPROM address zero is reserved.

Data @1,13,11,2,5,3,7,9,8,14,2,16 etc etc you get the drift...

PIC powers up, reads EEPROM location 0..., adds ONE, and stores it back to location zero...

READ 0,DataA
DataA=DataA+1
If DataA>126 then DataA=DataA-127
WRITE 0,DataA

This ensures on the next power-up, we have an incremented number... now we read the memory location kndly provided...

READ DataA,RandomValue

hey presto... a totally random value to start todays sequence with... you don't need to add by ONE... why not add three or seven or forty-two...

Now... all you do is for this evenings sequence just continue reading sequentially from that point (when you exceed 127, you rotate back to address 1 and continue). Totally random, no extra hardware, cheap, cheerful, easy, and Melanies comission cheque is in the post...

Melanie
- 7th November 2004, 21:00
Actually, here's a real easy way to get a fresh seed for your Random function every time you power up... no description... see if you can figure it...

RandomSeed var Byte

PIC powers up and runs this ditty...

Read 0,RandomSeed
RandomSeed=RandomSeed+23 ' best with any ODD number here
Write 0,RandomSeed

RandomSeed now contains a fresh seed every time you power up... three lines of code replaces your NE555 and a heap of headaches.

Since the EEPROM has only got a lifespan of around 100,000 writes... let me see that means your product should die sometime after 270 years - I trust the warranty would have exprired by then...

Melanie

bartman
- 7th November 2004, 22:02
Actually, I think you are describing what I was thinking after reading the whole eeprom thing. I still hadn't figured out how to really use the new line of thought.

RandomSeed is set as a Byte variable

We read from address 0 of the eeprom then add something to it and save it for next time. This keeps it always changing.

I'm not sure how to implement that yet though.

First, how does it get a value to begin with at address 0?

More code would be required to keep the value less than 256 correct?

Now, I still want to do this with nothing but 0 and 1 as the values so I think I still need to use Random in conjuction with whatever is in eeprom. I don't fully understand the workings of Random. As I get it currently it is just blazing along on a pre-determined course and every time Random is invoked it picks off a number which I can do math on to make 0 or 1. When we talk about seeding it are we just talking about giving it a new starting point?

I was checking out the data sheet on the 12F629 which is still my preference and see that it has 128 bytes of eeprom so if I can see this idea clearly and if I wrap my head around it correctly it would be much better than the 555 in the mix I agree.

Bart

Melanie
- 7th November 2004, 22:46
Ignore my first example - it's actually unnescessarily complicated. Chosing the second example only...

Pic Powers Up and executes this code...

RandomSeed var WORD
LightSelector var BYTE

Read 0,RandomSeed.Lowbyte
RandomSeed.Lowbyte=RandomSeed.Lowbyte+23
' best with any ODD number here
Write 0,RandomSeed.Lowbyte

(The starting value in EEPROM at location zero is irrelevant. It can itself be Zero).

At this point we have a WORD value of 'something' (which is different each time the PIC powers up)... we now use this to seed the Random sequence for this evenings light show...

Loop:
RANDOM RandomSeed

Now, we've got a 16-bit random value... but we're only interested really in the bottom 4 bits...

LightSelector=RandomSeed & $000F

Lightselector now contains a value between 0 and 15 which is used to select the next light to sequence...

Gosub BlinkyLight

This now Blinks our Light for whatever length of time, then...

Goto Loop

we loop around for the next Random light to be selected.

Tomorrow, you will notice we start with a new Random value in EEPROM to which we add our constant and store. Therefore tomorrows Random sequence will be seeded with a DIFFERENT start value, so the entire light show will be different. Ad nauseum each night forever (or until EEPROM location zero wears out)... but since the EEPROM is only written to ONCE each evening, we've got 270 years of evenings to play with...

This pretty much is the core of your ENTIRE program just handed to you - there is no more, this is it in it's entire complexity. Just add your I/O and your Config Fuses and you're done.

bartman
- 7th November 2004, 23:16
Well to you it might be the whole core, but to me it's just so much confusion! :-)

I am sure it is what I want, but until I understand it it's still like a puzzle waiting for me to figure it out.

We're still not dealing with 0 and 1 as the random numbers. Generating something from 1 to 16 means 16 lines of IF...THEN or some such to branch. By using 0 and 1 I can set each of the four output pin as high or low then use a fifth pin that "turns on" the 74HCT. Smaller program.

That doesn't mean the eeprom idea doesn't still work. I just can't understand it all yet to see how it works so I can use it. It's all giving me a headache! I am going back to study further your code.

Thanks.

Bart


P.S. I'm still working on understanding the fuses thing. I gather I need a resistor from the +5 to MCLR pin and the programmer has a box to either check or uncheck MCLR, but there is nothing in the help file that explains when to check or uncheck. I also read that MCLR doesn't need anything and one circuit diagram I saw doesn't have the pin going anywhere.

bartman
- 8th November 2004, 01:16
Okay. I see the problem here. I am trying to see this as "the big picture" when really I need to focus on the blocks that built it. If I can understand those then I can get this.

Let’s just look at RANDOM and how you showed me to use this. Here is my take on it:

RandomSeed var WORD

Read 0,RandomSeed
RandomSeed=RandomSeed+23 ' best with any ODD number here
Write 0,RandomSeed

Loop:

RANDOM RandomSeed


(Now we have a random number in RandomSeed between 1 and 65525 correct? Let’s say this number is 3245 just for an example. Here is what I wasn’t getting and I had to read the manual again to hopefully get this. The "Seed" is based on whatever is in that variable RandomSeed. A calculation is performed on that variable to get the random number. If we didn’t use eeprom the seed is really zero. The first time we use it the seed in eeprom it is also zero. It changes after that. Am I even close to correct on this? That is why it will always produce the same sequence each time unless the variable that is used as the seed is changed.)

Then, if I did this instead:

RandomSeed var WORD

Read 0,RandomSeed
RandomSeed=RandomSeed+103 ' best with any ODD number here
Write 0,RandomSeed

Loop:

RANDOM RandomSeed

(The random number generated would be different if all things were equal than the first example of 3245 correct? It is that way because I used a different factor to add to the seed - right?)

I’m hoping I am explaining myself correct because I do not want to get too deep in mud. I just want to make sure I understand how RANDOM really works. That is first then I can address how this gets deeper. I’ve been going over your code word for word to figure it out.

Then to address part of your code that is more confusing.

You define:

RandomSeed Var Word, but then you use RandomSeed.Lowbyte later. What is this "Lowbyte" part of this? I don’t see any reference to this in the manual.

Bart

Melanie
- 8th November 2004, 02:28
Lets set this piece by piece.

1. RandomSeed in my FINAL example is a WORD (16 bits) because the RANDOM command works on a Word variable, so we need a WORD.

2. RandomSeed.Lowbyte only acts on the Lower 8 Bits (the LOW BYTE of the Word - yes it's in the manual). Just as RandomSeed.HighByte would act on the upper Byte (upper 8 bits of the word).

3. EEPROM locations are BYTE sized (8 Bits).

4. When the PIC powers up, RandomSeed=$0000.

5. 1st time around we go to EEPROM addess Zero, and load the LOWBYTE of the RandomSeed Word with the contents. The initial Contents will be zero.

6. In my example we then add 23 to it. RandomSeed is now 23.

actually where I wrote...

RandomSeed.Lowbyte=RandomSeed.Lowbyte+23

I could just have left it as...

RandomSeed=RandomSeed+23

because it makes no difference in the scheme of things as adding 23 WILL act on the Lowbyte anyway!

7. We save the lower 8 bits (LowByte) back to EEPROM. EEPROM location zero now has 23 in it.

8. We now use 23 to itterate our first RANDOM function.

9. We only need the bottom four bits which will give us a 0-15 range.

---

Next Evening... we get to step 5 above and EEPROM address had 23 in it. We add another 23 and save the value 46 to EEPROM. We now have the value 46 to seed our RANDOM instruction.

---

On the third evening the seed will be 69... and so forth.

---

However, eventually we will spill out of a BYTE (8 bits, but we will only save the lower 8 bits of the RandomSeed word (we don't need any more than that) to be our starting point for the next day.

----

Your example is erroneous because RandomSeed is a WORD and you cannot READ or WRITE a WORD to EPROM in a single operation... you have to split it into two bytes and save each byte into separate EEPROM addresses. But like I said above, in your application saving the just lower 8 bits suffices.

-----

Once you have a variable holding a value 0-15, you can easily convert it to a 16-bit variable for shifting out of your chosen I/O to your peripheral driver.

bartman
- 8th November 2004, 03:49
Ignoring all of this for a second.

Am I right regarding the RANDOM generation and seeding? As in, the variable contents is the seed and using two different seeds would change the result? Did I get that much right anway? :-)

lowbyte as one word isn't in the manual. low and byte as separate words are, of course so what section should I be looking in to see this? I'm using the manual for PicBasic downloaded from the site where it can be purchased.

I may need to understand lowbyte and highbyte to make this work, but I'm not 100% sure since I don't care if it generates 0 to 15 or 1 to 65525 since I'm going to boil the results down to 0 and 1 anyway (at least that's my theory for now).

I still have the headache.

Bart

mister_e
- 8th November 2004, 04:55
Bartman >lowbyte as one word isn't in the manual. low and byte as separate words are, of course so what section should I be looking in to see this? I'm using the manual for PicBasic downloaded from the site where it can be purchased.


In a word you have 16 bits or 2x8 bits or 2x1 BYTE. LOWBYTE and HIGHBYTE are the 2 separate BYTE

MyWORD = %1111000000001111

MyByte1=MyWORD.HIGHBYTE
MyByte2=MyWORD.LOWBYTE


===========================

MyByte1 will return 11110000 Binary or F0 hex
MyByte2 will return 00001111 Binary or 0F hex


LOW is a function to access PORT pins. LOW will place pins, bits to low level.

LOW PORTA.0 ;will place PORTA RA0 pin to low level
LOW PORTA ;will place all PORTA pins to low level

===================================

RANDOM is a function of PICBASIC who provide you a pseudo-random value in a WORD size variable, 16 bits, range from 0-65525. So if you want to use it in your application, you'll need to use a range from 0-15. In this case you'll need only 1 BYTE to give you range from 1-255, after that reduce the range to 0-15.

SO...

RANDOM MyVar

Range0_255=Myvar.LOWBYTE
Range0_15=Range0_255 & $0F ; logical operation to isolate the 4 Less Significant Bits

ex:

Range0_255 = %10101010

Range0_15=Range0_255 & $0F

Range0_15 will return 1010 Binary , A in hexadecimal, 10 in decimal

bartman
- 8th November 2004, 05:19
Okay. I see what you are talking about. I did see in the manual that a word (W0) is made of two bytes being B0 and B1. That is all well and to some extent I understand it. Two Bytes are needed to hold a HEX word since HEX is twice the size of a byte.

That still doesn't explain where the words lowbyte and highbyte come from to use them the way they are being used in the examples. How would I know this reading the book that these words exist as "lowbyte" and "highbyte" after something else? right now I feel like there is a hidden page of information I'm not seeing.

I *think* I actually grasp the pin HIGH and LOW stuff as that is where I originally started with understanding how I had to drive the multiplexer.

I'm still curious if my understanding of RANDOM is how RANDOM works. Let's get to that then I'll tackle the high and low bit stuff.

Bart

mister_e
- 8th November 2004, 05:45
bartman>That still doesn't explain where the words lowbyte and highbyte come from to use them the way they are being used in the examples. How would I know this reading the book that these words exist as "lowbyte" and "highbyte" after something else? right now I feel like there is a hidden page of information I'm not seeing.


in my PBP Pro V2.45 book it's at the page 23.



Bartman>I'm still curious if my understanding of RANDOM is how RANDOM works. Let's get to that then I'll tackle the high and low bit stuff.

IMO you dont need to know how it's working since it's doing what you want :)

RANDOM is a built-in function that comes with PICBasic PRo & PicBasic standard who generate Pseudo random numers. This is all you need to know.

bartman
- 8th November 2004, 05:56
I bet you'd be hard pressed to find those words in the PicBasic manual. I'm not looking at the Pro version. Is it a Pro command that doesn't translate to the cheap version?

I don't need to know the math that happens with Random, but I still want to know how it is seeded and how that seeding affects thing. It matters to me since it helps me understand how I'm going to eventually use this idea to my ends. AND, at least I know if I have some grasp of what I've been trying to say in the above examples.

Bart

mister_e
- 8th November 2004, 06:12
RANDOM is available for both compilers.

bartman
- 8th November 2004, 06:19
I'm referring to "Lowbyte" and "highbyte". Those terms are NOT used in the cheap version manual. I just looked them up in the PRO version and yes, they are there.

Since I am NOT using the PRO version I'm basing everything on the basic, ie, cheap, version of the program. Hence my total confusion as to what to do with these words in my examples.

So, I assume that either there is different terminology for the basic program or it doesn't work in the basic program? I can go back and look again now that I see what it is an alias for.

RANDOM itself is fine I just want to know how the seeding part affects the outcome. Call it curiosity on the road to understanding.

Bart

mister_e
- 8th November 2004, 06:35
O.k, now i see... stupid french i am...


if you don't have HIGHBYTE and LOWBYTE function in standard PICBASIC, i suppose you'll be able to do it like this.

MyRandom VAR WORD
MyResult VAR BYTE

RANDOM MyRandom
MyRandom=Myrandom & $000F
MyResult = MyRandom

Melanie
- 8th November 2004, 09:22
I keep forgetting that not everyone has PBP...

Unfortunately not having PBC I'm relying on the manual only...

RandomSeed is W0
I don't know if B0 or B1 is the Lowbyte... let's say it's B0
LightSelector is B2

so the code would go something like...

Read 0,B0
W0=W0+23
Write 0,B0

Loop:
RANDOM W0
B2=W0 & $000F
Gosub BlinkyLight
Goto Loop

Does this make things any clearer?

bartman
- 8th November 2004, 14:51
Okay, now I have some idea of what is being spoken here! Thank you.

But can my question about seeding RANDOM be answered so I can give all this more consideration to get to the guts of the matter?

Thanks.

Bart

Melanie
- 8th November 2004, 15:31
Random works thus...

You provide RANDOM with a WORD variable, the contents of which is a number anywhere between 0-65535. This number is your 'seed'.

When RANDOM executes it performs an itteration on the number you have provided, and returns with another number (in the same variable) which to all intents and purposes will be totally random. Your initial variable is replaced by a new one.

The fact is if the seed is the same, then the result is the same (ie it's a repeatable random itteration) known as pseudo random (rather than true random). You can then use this result for the next RANDOM call, etc etc.

According to MeLabs, their RANDOM instruction will never return a zero result.

Melanie

bartman
- 8th November 2004, 17:10
Okay. So that is why the sequence will always be the same with RANDOM when it starts up because it is always pulling a ZERO as the seed number if left alone because no other variable has been defined?

So, taking this one step further. IF I had 5 of the exact same programs running on 5 identical projects, but the projects were not connected in any way and I could power them all at the exact same time then each of them would create random numbers in the same order?

If I wanted to really make things even more random (from the observers perspective) I could add a RANDOM number to the RANDOM variable that we are speaking of instead of using the "+23" and saving that? In effect not ever knowing what the darn thing is going to add and save in eeprom for the next time? Granted this would be more "random" than I need, but once again, it helps me understand the theory.

I'm at work so I can't totally put my mind to the high and low byte issue right now, but now that I'm seeing the applicable syntax it isn't all that much of a stretch to grasp it.

Thanks.

Bart

Melanie
- 8th November 2004, 18:04
If you enter RANDOM with the same number (be it zero or otherwise) it will always produce the same repeatable sequence.

If you had your five projects, all identical, all powered up on the same day for the first time, they will all produce the same result. To ensure that didn't happen, ensure the contents of EEPROM location zero differs for each project (see DATA statement), or power each PIC on/off a different number of times (since location zero alters each time) and the projects will then all be following a different switching pattern.

Yes you could add a Random result instead of 23 as you say, but it won't make it any more random. This is because we are going to cycle through 256 possible Random start sequences anyway (as EEPROM location zero is a BYTE variable), and therefore a BYTE only has 256 possble states with which we can start seeding.

bartman
- 8th November 2004, 20:06
Yes, things are clearing up.

Now, given that eeprom is only storing a BYTE and not a WORD I can understand that generating a RANDOM WORD to try and stuff into the eeprom is pointless, but how is adding 23 any less pointless? If the eeprom is storing a BYTE of 0 and 1's isn't 23 a WORD? I know that 23 is well within the 256 limit, but is there some internal math going on that is saying, "okay, I'm going to convert that 23 to binary to make up my byte then add it to what is there already" that it CAN'T do with 65536 which is beyond the 256 limit?

So, I also assume that to stuff a WORD into eeprom there is a way to separate the low and high bytes and put into two eeprom addresses?

This is getting past the random issue now. I am looking at the inner workings of word and byte.

Further. Is this written correct? You wrote:

Read 0,B0
W0=W0+23
Write 0,B0

As I see this we are just putting the same information back into address 0 without really adding anything to it since the +23 is going on a word variable. Is line two possibly b0=w0+23 then only the lowbyte is being written back?

Bart

Melanie
- 8th November 2004, 21:49
+23 is just an ODD number. You can have any ODD number here - even ONE. If you use an even number, you will not have 256 random seedings, but 128. I'll leave you to figure why.

If W0 is made up of B0 and B1, then by changing either of those don't you change W0 accordingly? And if you change W0 then don't you similarly affect B0 and B1? Please see the table on page 22 of the PBC manual along with the first paragraph of Section 4.6...

bartman
- 8th November 2004, 22:10
I'll have to think on the even/odd number thing.

I get you on the w0, b0 and b1. They are attached to each other so anything done to one affects one or both of the remaining two.

If I had this:

w0=3250
write 0,b0
write 1,b1

That would write the entire WORD to eeprom correct?

And, if I did this:

read 0,b0
read 1,b1
number = w0

The variable called "number" would be intact as 3250? (never mind that I probably don't need to read it since it is still intact as w0 to begin with)

Bart

bartman
- 9th November 2004, 04:31
Okay, I've taken the code sample that was based on PBC and wrote out how I see the bits being used at a line by line level. I came up with this:

* Program starts for the evening for the first time ever:

<b>Read 0,B0</b>

(B0 now contains %00000000 as it has not had anything wrote to it yet)

<b>W0=W0+23</b>

(W0 now contains %0000000000010111 as W0 is a 16 bit WORD and 23 was added to, basically, zero)

<b>Write 0,B0</b>

(B0 now contains %00000000 as B0 just saves the first 8 bits of the 16 bit WORD to eeprom)

<b>Loop:
RANDOM W0</b>

(W0 is a new RANDOM 16 bit WORD seeded with %0000000000010111 as W0 has not been reset yet with a power down and I have to assume the 16 bit value is stored somewhere other than eeprom for general operations)

<b>B2=W0 & $000F
Gosub BlinkyLight
Goto Loop</b>

(Not addressed in this example since I'm only interested in the eeprom seed value.)

As I see this, each time the chip starts up it is only reading and writing a ZERO back to the eeprom for the next seed. Perhaps if B1 was used instead of B0 or even both?

So, what am I missing here with the bits and writing out what is happening at a BIT level?

Bart

PS. hold the phone. I think I answered this myself. The bit count starts on the right and moves left, not on the left and moving right. Am I right? If I do have my example backward here then B0 is still correct and it would save something different each time.

I'm still working on the odd and even issue though.

bartman
- 9th November 2004, 05:40
Now I want to tackle the bitwise AND & syntax.

I think I am clear now on how we've come up with our 16 bit WORD seeds and what not.

For this example it is W0=%0000000011101101

When something like this is done:

<b>randomlight=W0 & $000F</b>

it is also like saying:

<b>randomlight=W0 & %1111</b> correct?

It is comparing the first four bits of the word so it looks like this:

<b>%0000000011101101</b> - original word
<b>%0000000000001111</b> - AND compare on bitlevel (narrow it down to 16 or less)
<b>%0000000000001101</b> - result of the compare

No matter how you compare with the second set of bits the results is the first four bits of the first set. The "&000F" is just a handy way of stripping away the bits that aren't needed?

My result comes back as a decimal 13 in this case.

But if I do it wanting to pick from 15 lights instead:

<b>%0000000011101101</b> - original word
<b>%0000000000001110</b> - AND compare on bitlevel (narrow it down to 15 or less)
<b>%0000000000001100</b> - result of the compare

Decimal 12

If I wanted to I could compare any number of bits by adjusting the second row of numbers so I could use & %00FF to come up with:

<b>%0000000011101101</b> - original word
<b>%0000000011111111</b> - AND compare on bitlevel (narrow it down to 255 or less)
<b>%0000000011101101</b> - result of the compare

Decimal 237

<b>%0001011011101001</b> - original word
<b>%0000000011111110</b> - AND compare on bitlevel (narrow it down to 254 or less)
<b>%0000000011101000</b> - result of the compare

Decimal 232

The only problem here is that I don't see where the results are <em>seldom</em> different in the final row than what the original first few bits in all the examples I also did on paper unless the second row has lots of zeros compared to the first row so I think I am missing a key point?

It is getting a little confusing now understanding the exact function of bitwise AND. Can someone expand to fill in the gaps here?

Am I, at least, close on this operation?

Thanks.

Bart

Melanie
- 9th November 2004, 12:49
I'm on the run today, so ultra-fast replies...

* Program starts for the evening for the first time ever:

Read 0,B0

(B0 now contains %00000000 as it has not had anything wrote to it yet)

W0=W0+23

(W0 now contains %0000000000010111 as W0 is a 16 bit WORD and 23 was added to, basically, zero)

...and B0 has 00010111 inside it!

Write 0,B0

(B0 now contains %00010111 as B0 just saves the first 8 bits of the 16 bit WORD to eeprom)

We're assuming all along that B0 is the LOWER 8 bits (bits 0 thru 7). If it happens to be the UPPER (bits 8 thru 15), then rather than playing with B0, we simply play with B1 instead. You can find out which is which through simple experimentation.

Loop:
RANDOM W0

So, first time around, 23 gets saved to EEPROM, next time its 46, next time it's...

So, what am I missing here with the bits and writing out what is happening at a BIT level?

I think you figured it!

You're smack-on with the bitwise compare examples. I don't see you're confusion, all your examples are 100% correct.

bartman
- 9th November 2004, 14:57
I guess my confusion is in the result. I was expecting it to be <em>more</em> different than the original if that makes sense. I guess it really is since using %00001111 on something like %10011101 it does make it different.

So, in your examples all that & $000F is there for is to get rid of ALL other bits except the first four? That's how it is used in this project, but & could have other uses besides "bit stripping"?

In fact, this could also be used for my case of only wanting a "0" or a "1" by making it $0001 or %00000001

<b>%0001101101011011</b>
<b>%0000000000000001</b>
<b>%0000000000000001</b> results

Decimal: 1

<b>%0001101101011010</b>
<b>%0000000000000001</b>
<b>%0000000000000000</b> results

Decimal: 0

I'm getting ideas....

The even/odd still has me puzzled, but I will need to read the thread again now and see if it makes more sense.

Thanks,

Bart

bartman
- 10th November 2004, 04:10
Originally posted by Melanie
+23 is just an ODD number. You can have any ODD number here - even ONE. If you use an even number, you will not have 256 random seedings, but 128. I'll leave you to figure why.


Okay. Honestly, I don't see this. The closest thing I can come up with it that by using an ODD number the first bit will alternate between 0 and 1 where as if an EVEN number is used the first bit will always be 0 which would mean 128 bytes possibilities wouldn't come up.

In reality though we're adding a number to a RANDOM number which could be odd or even and always saving just half the WORD anyway so all 256 possbilities for the seed number should come up over time.

This is the only thing I can think of, but it brings back another point.

If I continue to add a number to the eeprom eventually, as you mentioned, the bytes are going to add up to more than 256. Using 23 it would take no time at all to "fill up". How is this handled by the program?

<b>Read 0,B0
W0=W0+23
If W0>65535 then... </b> ?? What the heck happens. It can't be more than 65535. Does the system truncuate it to 65535 so I can still <b>Write 0,B0</b> ?

Or does the result cause a crash?

Thanks.

Bart

Melanie
- 10th November 2004, 09:35
No it won't crash... you'll just ignore the upper 8 bits... it'll work like this...

The first column is initial EEPROM Contents, the second column is after you've added 23 (remember 23 is just an ODD number I've pulled out of a hat), and the third column is what is saved back to EEPROM for the next evening...



Start Random Saved to
EEPROM seed EEPROM
Value (+23) Value
------ ------ --------

0 23 23
23 46 46
46 69 69
69 92 92
92 115 115
115 138 138
138 161 161
161 184 184
184 207 207
207 230 230
230 253 253
253 276 20
20 43 43
43 66 66

etc etc

Since only the lower 8 bits of the word are saved, the saved value can only be in the range 0-255.

Can you see now what's happening in your EEPROM location?

when you get to 253 in EEPROM, you add 23 and W0 becomes 276, but because you're only saving the eight lower bits of W0 back to EEPROM, the actual value you save will be 20...

And yes, with the ODD/EVEN offset, if you use an EVEN offset you will never seed an ODD number, so you can't possibly have more than 128 seed values, whereas if you use an ODD number, you will eventually rotate through all 256 values.

This arrangement gives you a nice seeding whereby the homeowner should never be able to recognise any sequences as repeating themseves... in theory it should be 256 days before the sequence repeats.

Melanie

bartman
- 10th November 2004, 14:55
Perfect sense.

When I wrote last night I was writing +23, but in my mind I was thinking that we were adding a random number not a constant so I was seeing both odd and even possibilities being wrote.

So, I guess that indirectly I knew the answer! :-)

Couldn't this:

Read 0,B0
W0=W0+23
Write 0,B0

also be written as:

Read 0,B0
B0=B0+23
Write 0,B0

Even when I use RANDOM W0 later it should know W0 to be somethig like %0000000011011011 since a B0 value was previously written at start up?

I'm going to post a bit of code sometime today. I've been thinking about it using my new found knowledge of bit locations. I'm curious if it would work.

Thanks.

Bart

Melanie
- 10th November 2004, 21:29
Yes you can do as per your example, as long as your RANDOM statement uses W0 (or it's assigned name).

bartman
- 15th November 2004, 05:54
One other thing that we discussed briefly.

The B0 or B1 bytes store only the bottom or top byte of the word so the maxium value in either would be 256 so we get 256 seeds if we use the odd number addition. Good for one different random cycle each night for 256 nights.

If I read and write BOTH B0 and B1 to eeprom addresses 00 and 01 then, using the odd number addition. I could get up to 65535 seeds correct?

Or, as you say, enough for 179 years of a different random combination each night? More than anyone could keep track of even if they wanted to.

Right or wrong?

Bart

Melanie
- 15th November 2004, 14:17
Right... but what's the point? As if anyone's going to even remember 256 combinations.

bartman
- 15th November 2004, 14:42
No point. Just wanted to make sure I had my head around it.

Can't you remember 256 combinations? What kind of <em>Simon</b> player are you? :-)

Bart

Len
- 5th October 2005, 17:51
dumbdumbdumb!