Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Getting a more random seed from the ADC

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
CBailey

Bascom Member



Joined: 07 May 2015
Posts: 108

blank.gif
PostPosted: Tue Dec 12, 2023 2:35 pm    Post subject: Getting a more random seed from the ADC Reply with quote

I accidentally posted this in the Arduino forum but it's not exactly arduino-related.


I grabbed this from an old post by Jabberwocky (https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=8778&highlight=random+seed), but can't get it to work. When I run it, I always get 63 as an output. I haven't had reason to use the ADC yet so I'm probably doing something dumb.



Code:



$programmer = 22                                            'ARDUINO (using stk500v1 protocol)
$regfile = "m328pdef.dat"                                   'Set the AVR to use - ATMega328.
$crystal = 16000000                                         'Set the AVR clock.
   '
$hwstack = 48                                               'Set the capacity of the hardware stack.
$swstack = 80                                               'Set the capacity of the software stack.
$framesize = 80


' ---------------------------------------------
'  * PCF8574 I2C LCD Adapter settings *
'----------------------------------------------
$lib "i2c_twi.lib"                                       'Incorporate the hardware I2C/TWI library.
Config Twi = 100000                                      'I2C bus clock = 100KHz
Config Scl = Portc.5                                     'You must specify the SCL pin name.
Config Sda = Portc.4                                     'You must specify the SDA pin name.
I2cinit                                                  'Initialize the SCL and SDA lines of the I2C bus.

Dim Pcf8574_lcd As Byte : Pcf8574_lcd = &H4E             'PCF8574 slave address. (&H40,&H42,&H44,&H46,&H48,&H4A,&H4C,&H4E)
Dim Backlight As Byte : Backlight = 1                    'LCD backlight control. (0: off, 1: on)
$lib "lcd_i2c_PCF8574.LIB"                               'Incorporate the library of I2C LCD PCF8574 Adapter.
Config Lcd = 16x2                                        'Set the LCD to 16 characters and 2 lines.
Initlcd



'-------------------------------------------------------
' Here we make a more random seed
'

Dim I as Byte
MakeSeed:
cls
CONFIG ADC = free, PRESCALER = 2
Dim Rnd_word as word
'Dim I as byte
Dim Bit_num as byte
Dim Adc_word as word
lcd "Random Gen:"
Rnd_word = 0
For I = 1 To 255                                            'n times the whole process to mix the value up well
   For Bit_num = 0 To 25
      Adc_word = Getadc(0)
      Adc_word = Adc_word And 1
      Rotate Rnd_word , Left
      Rnd_word = Rnd_word Xor Adc_word
   Next
Next
''__rseed = Rnd_word                                          'use random value to set the seed or for whatever
'cls
lcd Rnd_word

waitms 100

Goto MakeSeed


 


(BASCOM-AVR version : 2.0.8.6 )
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Tue Dec 12, 2023 4:03 pm    Post subject: Re: Getting a more random seed from the ADC Reply with quote

CBailey wrote:
I haven't had reason to use the ADC yet so I'm probably doing something dumb.

You got that correct.

1st - read the help, keyword: Config ADC
2nd - think about what a Reference is for.
3rd - open the 'Single'-conversion sample 'adc.bas', make it work
4th - read the appropriate datasheet section
5th - try to switch over to free run

Hint 1, a prescaler of 2 and thus 8MHz ADC-clock results in (13 clocks per sample) 615400 ADC sample frequency, which is far too high.
64, 128 or AUTO as prescaler match better.
Hint 2, as you can get from 1st, the line 'Adc_word = Getadc(0)' won't be compiled, you need to control the 4 MUX-bits in ADMUX and read the value via 'result = ADC'
Back to top
View user's profile
CBailey

Bascom Member



Joined: 07 May 2015
Posts: 108

blank.gif
PostPosted: Wed Dec 13, 2023 2:11 am    Post subject: Reply with quote

Thanks for the reply.

As I'm trying to create a source of noise instead of actually doing any ADC stuff, I'm guessing your comment means I'm close. Smile

While I have looked at the help, it could be more clear as to what applies to the ATMega and the xmega. What I have so far is this:

Code:

Dim I as word
Dim AdcJunk as Word
MakeSeed:

CONFIG ADC = free, PRESCALER = 2,  REFERENCE = off

Dim Rnd_word as word
'Dim I as byte
Dim Bit_num as byte
Dim Adc_word as word

'Rnd_word = 0
For I = 1 To 2550                                            'n times the whole process to mix the value up well
   For Bit_num = 0 To 250
      AdcJunk = Getadc(0)
      AdcJunk = Adc_word And 1
      Rotate Rnd_word , Left
      Rnd_word = Rnd_word Xor AdcJunk
   Next
Next
''__rseed = Rnd_word                                          'use random value to set the seed or for whatever
cls
lcd "Random Gen:"
lcd Rnd_word

waitms 100

Goto MakeSeed

 


I still get a zero output. What am I doing wrong?
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Wed Dec 13, 2023 3:53 pm    Post subject: Reply with quote

CBailey wrote:
I still get a zero output. What am I doing wrong?

Alas it's not enough to thank me for my reply, if you miss my advice.

1. You need a reference.
If you have physically connected the ARef-pin (see datasheet) of your ATM328 to VCC or another suitable voltage source, then you're fine with parameter 'off', as well without the parameter 'REFERENCE'.
Otherwise you need to tell the compiler which internal source for REFERENCE you want.
As you won't find the AtMega328 mentioned in this context by the help, you can use parameters for m48/88/168, as this is the same processor family.

2. You use 'AdcJunk = Getadc(0)' in your code and I wrote 'the line 'Adc_word = Getadc(0)' won't be compiled'.
Do you think by renaming the variable to AdcJunk anything changes?
I also gave you the solution with 'read the value via result = ADC'. This becomes 'AdcJunk = ADC'

3. Your code contains again 'PRESCALER = 2', while I wrote 'a prescaler of 2 ... which is far too high. 4, 128 or AUTO as prescaler match better.'
This has the effect that the internal sample capacitor of the ADC is charged too often, too fast, which quasi makes the ADC0 pin very low impedance.
What I understand from this approach is, that either a floating or with some noise driven ADC0-pin should be used for randomness.
Sampling too fast may be contra-productive therefor.

4. As you also omitted to care about the ADMUX-register, at least MUX is at its default &b0000, which selects ADC0 as input.
Be aware that you need to control MUX3..0 in case you want to use a different pin than ADC0.

In short, point 2 is the main error, the variable AdcJunk will keep its initial value, which is zero.
Short thereafter point 1 may follow, then in order 3 and 4.
Back to top
View user's profile
laborratte

Bascom Expert



Joined: 27 Jul 2005
Posts: 299
Location: Berlin

germany.gif
PostPosted: Wed Dec 13, 2023 4:43 pm    Post subject: Reply with quote

@MWS

I agree with point 1 & 3 (and in addition I ask myself: why the heck does this loop has to run 637500 times?), but at least my compiler (2.0.8.1) translates
Code:
adc_word = getadc(0)
 
pretty solid to
Code:
lds R16,ADMUX
andi R16,&B11110000  'MUX3:0 = 0
sts ADMUX,R16
'and, for short, in pseudo-word assembler:
lds R24:R25,ADC
ldi X,{adc_word}
st X,R24:R25
 


So, I don't get your point 2.
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Wed Dec 13, 2023 7:48 pm    Post subject: Reply with quote

laborratte wrote:
but at least my compiler (2.0.8.1) translates pretty solid

The time I wrote first about GetADC() the result was the way, that while simulating with AVR Studio 4 I was not able to set a breakpoint on ' result = GetADC(0)', simply because this line held no opcodes.
Which was the reason for my statement.

Checked again with a small sample on a fresh 2.0.8.6 and it compiled ok, the ADC-channel can be thus easily set by GetADC(channelx) while in the same the ADC-result is returned.
Which is good news for the TO.

Thank you.
Back to top
View user's profile
laborratte

Bascom Expert



Joined: 27 Jul 2005
Posts: 299
Location: Berlin

germany.gif
PostPosted: Wed Dec 13, 2023 11:37 pm    Post subject: Reply with quote

MWS wrote:
(...) with AVR Studio 4 I was not able to set a breakpoint (...)

oh yes, this sounds very familiar to me Very Happy
Back to top
View user's profile
CBailey

Bascom Member



Joined: 07 May 2015
Posts: 108

blank.gif
PostPosted: Thu Dec 14, 2023 4:50 am    Post subject: Reply with quote

Thanks for the replies. I did get it working. Below is my code in the hopes it can help someone.

Code:

CONFIG ADC = Single, PRESCALER = Auto,  REFERENCE = Avcc

Dim Adc_word as word
Dim Bit_num as Byte
Dim Rnd_word as word

For I = 1 To 72
   For Bit_num = 0 To 7
      Start ADC
      Adc_word = Getadc(Bit_num)
      Stop ADC
      Rotate Rnd_word , Left
      Rnd_word = Rnd_word Xor Adc_word
   Next
Next
___rseed = Rnd_word
 


I had it loop through all the ADCs as I found some were more random than others. It doesn't appear to be perfectly random but more than enough for my purposes. I turn the ADC on and off in the hopes it might give the ADC a more bumpy ride and spit out more randomness but it didn't appear to make much difference.
Back to top
View user's profile
hgrueneis

Bascom Member



Joined: 04 Apr 2009
Posts: 902
Location: A-4786 Brunnenthal

austria.gif
PostPosted: Thu Dec 21, 2023 10:34 pm    Post subject: Reply with quote

One way would be, to feed the ADC with a diode in between AC voltage and use an odd timing to get a random value. you can also combine it with variable data, like seconds and other changing data. Take multiple samples and mathematically result in a random number.
Just an input.
Regards Hubert
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum