, , . . . , Linux , : , .
, Wi-Fi, .
, , . , 3--1 RS232 (COM) . :
- , watchdog;
- p-n ;
- nRF24L01+ .
WRN : WDT (WatchDog Timer), RNG (Random Number Generator), nRF24L01+.

, , , rngd --rng-device=/dev/urandom. /dev/urandom , RNG, , .
( )

ATmega328P 20MHz. , , 32MHz , . , , . , , .
SPI USB-UART , , RS232 . , , . , KiCAD GitHub alexcustos/wrn-project pcb.
- C12 – , - ;
- Y1, C3, C4 – ;
- D1, R11 – , , ;
- PB1, R2 – RESET (pull-up) ;
- U1, C1, C2 – , 800mA , 100mA ;
- U2, R1 – , 20mA ;
- U3, C5, C6, C9, C10 – RS232-TTL ;
- P3, C11 – +5 +12V FDD 12V;
- P4 – ;
- P1 – ISP , ;
- P2 – RS232 ;
- P5 – RESET ;
- P7 – USB-UART.
RS232-TTL

ADM202EANZ Analog Devices , MAX232ACPE . Maxim.
R3, R4, R12 USB-UART . , . 1kΩ, , U3 .
SPI , . SPI , .
, . DTR (Data Terminal Ready) , .
, Q4 DTR . , . R6 , ; C7 – RESET.
, , JP1. , USB-UART .
p-n

p-n Q1. Vebo=6V, ( ) . , , 12V. p-n , . , p-n , . , , 1N4148, 100V.
: Q2 Q1; R5 - Q2; C8 Q2, ; (R7+R8) - Q3 C8; Q3 C8 (R7+R8); R9, R10 , 5V .
, KiCAD. , .
, . Edge.Cuts  , .
 , .
(Pads) . , . , , .
, pcbnew , . . , 1, . , , .
(Pad) E,  ,
,  . , ,
. , ,  ,
,  . , (Footprint) . , .
. , (Footprint) . , .
Perform design rules check  → Start DRC Problems / Markers Unconnected .
 → Start DRC Problems / Markers Unconnected .
, . View → 3D Viewer. Gerber (- PDF ) File → Plot → Gerber (Plot format), , : B.Cu, Edge.Cuts Plot, Generate Drill File → Drill File, .
KiCAD GerbView  , . , File → Print . B.Cu, Print frame ref . Real drill , , Small mark ( ) . , , .
, . , File → Print . B.Cu, Print frame ref . Real drill , , Small mark ( ) . , , .
- — Real drill , Dremel 0.8, - 3/4, 1.0, : , , DIP ;
- — Real drill , 1.0, , ;
- — Small mark, , 1.0 , 1.0 0.9, 1.1, ;
- — Real drill , , 3 1.0, , .
«». , . . , , .
(- ). .

180°C ( ) , . , , , . , - . .

, , . , , .

:
100 3% , , .
, . , : . , , , , .

. . , , . , 30°C , 23°C, . .

, , 2-3 . , , . 40-50 . , , .

. .

, . . ( ), , 5 , ( ) - . , . , , . - , .
, , , , .

, , .
( )

 :
( )


C++ AtmelStudio, GitHub alexcustos/wrn-project wrn. Arduino IDE Arduino. , . GitHub :
, : ATtiny85: .
. Optiboot — , Atmel AVR . , , , , .
, , , SPI . , , , .
, Ubuntu :
sudo apt-get install git gcc-avr binutils-avr gdb-avr avr-libc avrdude
:
git clone https://github.com/Optiboot/optiboot.git
cd optiboot/optiboot/bootloaders/optiboot
make atmega328_isp AVR_FREQ=20000000L BAUD_RATE=115200 LED=C0 EFUSE=FD HFUSE=DE LFUSE=F7 ISPTOOL=stk500v1 ISPPORT=/dev/ttyACM0
, , . :
BAUD RATE CHECK: Desired: 115200, Real: 113636, UBRRL = 21, Error=-1.3%
Real , , USB-UART , RS232-TTL . Error 0.0% , 1-2 , — .
20MHz BAUD_RATE 250000. RS232-TTL , ADM202EANZ 230000, 57600. 115200 , , . , avrdude , , .
FUSE-:
- EFUSE=FD – EEPROM 2.7V, FC (4.3V), USB 2.7V .
- HFUSE=DE – 512 , SPI ;
- LFUSE=F7 – full-swing , , XTAL2.
(ISPTOOL, ISPPORT) arduino , , - .
: optiboot_atmega328p_20MHz.hex. avrdude :
avrdude -C/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyACM0 -b19200 \
    -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xF7:m \
    -Uflash:w:"optiboot_atmega328p_20MHz.hex":i -Ulock:w:0x2F:m
, , : , , FUSE-, .
, , Optiboot , .
, . , .
SPI F_CPU. -DF_CPU=20000000L. , F_CPU.
main() , :
[C|W|R|N][0-99]:[1]:[2], , , — , . .
(struct) . , , . , . , -fpack-struct, AtmelStudio .
, , , . , . , — .
. , . , .
, EEPROM . .
(uptime). uptime . .
- , , , . uint16_t (~12.5 ).
8 . RF24/RF24Network, . , 1000 , 64 : 20000000 () / 256 (8 ) / 64 () ~= 1220, 256 * 64 * 1000 / 20000000 = 8192/10000 = 512/625 . TIMER0_OVF :
m += MILLIS_INC;  
f += FRACT_INC;  
if (f >= FRACT_MAX) {  
    f -= FRACT_MAX;  
    m += 1;
}
, , , .
, p-n , p-n - . . , .
, , .
, , , , , , , .
measure = read_measure();  
num_measures++;  
if (num_measures == measure_limit) {
    balance = false;
    
    if (pan_left > pan_right) fault = pan_left - pan_right;
    else fault = pan_right — pan_left;
    
    acceptable_fault = ((measure_limit - 1) / 256 + 1) * 3;
    if (fault > acceptable_fault) {
        
        
        if (pan_right > pan_left && threshold < uint8_t(-1)) threshold++;
        else if (pan_left >= pan_right && threshold > 0) threshold--;
    } else balance = true;
    ... 
    ... 
    if (balance && measure_limit) {  
        measure_limit = 0;  
        return false;  
    }
} else {  
    if (measure <= threshold) pan_left++;
    else pan_right++;
}
:
byte <<= 1;  
if (measure > threshold) byte |= 0b00000001;
rngtest rngd monobit . , , ADC «», . , :
byte ^= bit_flip;  
bit_flip = !bit_flip;
, , monobit . . 636 / dieharder . - 500MB. , . /dev/urandom. dieharder .
rngtestrngtest: bits received from input: 4195417088
rngtest: FIPS 140-2 successes: 209549
rngtest: FIPS 140-2 failures: 221
rngtest: FIPS 140-2(2001-10-10) Monobit: 21
rngtest: FIPS 140-2(2001-10-10) Poker: 70
rngtest: FIPS 140-2(2001-10-10) Runs: 59
rngtest: FIPS 140-2(2001-10-10) Long run: 72
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
 rngtest (/dev/urandom)rngtest: bits received from input: 4181721088
rngtest: FIPS 140-2 successes: 208937
rngtest: FIPS 140-2 failures: 149
rngtest: FIPS 140-2(2001-10-10) Monobit: 20
rngtest: FIPS 140-2(2001-10-10) Poker: 21
rngtest: FIPS 140-2(2001-10-10) Runs: 57
rngtest: FIPS 140-2(2001-10-10) Long run: 52
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
 dieharder#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  1.99e+07  | 871678203|
#=============================================================================#
             test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
  0:    diehard_birthdays|   0|       100|     100|0.23013568|  PASSED
  1:       diehard_operm5|   0|   1000000|     100|0.41464749|  PASSED
  3:     diehard_rank_6x8|   0|    100000|     100|0.83194246|  PASSED
  4:    diehard_bitstream|   0|   2097152|     100|0.98469009|  PASSED
  7:          diehard_dna|   0|   2097152|     100|0.82184561|  PASSED
  8: diehard_count_1s_str|   0|    256000|     100|0.63516902|  PASSED
 10:  diehard_parking_lot|   0|     12000|     100|0.15579947|  PASSED
 11:     diehard_2dsphere|   2|      8000|     100|0.94799044|  PASSED
 12:     diehard_3dsphere|   3|      4000|     100|0.16755480|  PASSED
 14:         diehard_sums|   0|       100|     100|0.00420819|   WEAK
 15:         diehard_runs|   0|    100000|     100|0.58812798|  PASSED
 15:         diehard_runs|   0|    100000|     100|0.23381862|  PASSED
100:          sts_monobit|   1|    100000|     100|0.11747720|  PASSED
101:             sts_runs|   2|    100000|     100|0.12598371|  PASSED
102:           sts_serial|   1|    100000|     100|0.11747720|  PASSED
102:           sts_serial|   2|    100000|     100|0.98806196|  PASSED
102:           sts_serial|   3|    100000|     100|0.93420112|  PASSED
102:           sts_serial|   3|    100000|     100|0.88625906|  PASSED
102:           sts_serial|   4|    100000|     100|0.81837353|  PASSED
102:           sts_serial|   4|    100000|     100|0.44680983|  PASSED
102:           sts_serial|   5|    100000|     100|0.30069422|  PASSED
102:           sts_serial|   5|    100000|     100|0.59918415|  PASSED
102:           sts_serial|   6|    100000|     100|0.94111872|  PASSED
102:           sts_serial|   6|    100000|     100|0.97775411|  PASSED
102:           sts_serial|   7|    100000|     100|0.71034876|  PASSED
102:           sts_serial|   7|    100000|     100|0.37205549|  PASSED
102:           sts_serial|   8|    100000|     100|0.62281679|  PASSED
102:           sts_serial|   8|    100000|     100|0.61865217|  PASSED
102:           sts_serial|   9|    100000|     100|0.12357283|  PASSED
102:           sts_serial|   9|    100000|     100|0.62028539|  PASSED
102:           sts_serial|  10|    100000|     100|0.70302730|  PASSED
102:           sts_serial|  10|    100000|     100|0.36150774|  PASSED
102:           sts_serial|  11|    100000|     100|0.02416524|  PASSED
102:           sts_serial|  11|    100000|     100|0.00210157|   WEAK
102:           sts_serial|  12|    100000|     100|0.15545193|  PASSED
102:           sts_serial|  12|    100000|     100|0.25167693|  PASSED
102:           sts_serial|  13|    100000|     100|0.19659046|  PASSED
102:           sts_serial|  13|    100000|     100|0.56538654|  PASSED
102:           sts_serial|  14|    100000|     100|0.15529368|  PASSED
102:           sts_serial|  14|    100000|     100|0.99005364|  PASSED
102:           sts_serial|  15|    100000|     100|0.15517199|  PASSED
102:           sts_serial|  15|    100000|     100|0.91135159|  PASSED
102:           sts_serial|  16|    100000|     100|0.70484328|  PASSED
102:           sts_serial|  16|    100000|     100|0.71149544|  PASSED
201: rgb_minimum_distance|   0|     10000|    1000|0.00000000|  FAILED
202:     rgb_permutations|   5|    100000|     100|0.72724154|  PASSED
203:       rgb_lagged_sum|   0|   1000000|     100|0.79186771|  PASSED
204:      rgb_kstest_test|   0|     10000|    1000|0.46365770|  PASSED
206:              dab_dct| 256|     50000|       1|0.53224869|  PASSED
207:         dab_filltree|  32|  15000000|       1|0.87205525|  PASSED
207:         dab_filltree|  32|  15000000|       1|0.28341671|  PASSED
208:        dab_filltree2|   0|   5000000|       1|0.69766563|  PASSED
208:        dab_filltree2|   1|   5000000|       1|0.68877816|  PASSED
209:         dab_monobit2|  12|  65000000|       1|0.99154840|  PASSED
 dieharder (/dev/urandom)#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  2.09e+07  |2043744116|
#=============================================================================#
             test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
  0:    diehard_birthdays|   0|       100|     100|0.04140546|  PASSED
  1:       diehard_operm5|   0|   1000000|     100|0.37860771|  PASSED
  3:     diehard_rank_6x8|   0|    100000|     100|0.51810908|  PASSED
  4:    diehard_bitstream|   0|   2097152|     100|0.87265669|  PASSED
  7:          diehard_dna|   0|   2097152|     100|0.28188785|  PASSED
  8: diehard_count_1s_str|   0|    256000|     100|0.01571303|  PASSED
 10:  diehard_parking_lot|   0|     12000|     100|0.27155245|  PASSED
 11:     diehard_2dsphere|   2|      8000|     100|0.56675436|  PASSED
 12:     diehard_3dsphere|   3|      4000|     100|0.95480977|  PASSED
 14:         diehard_sums|   0|       100|     100|0.00076186|   WEAK
 15:         diehard_runs|   0|    100000|     100|0.62119123|  PASSED
 15:         diehard_runs|   0|    100000|     100|0.79241488|  PASSED
100:          sts_monobit|   1|    100000|     100|0.76618520|  PASSED
101:             sts_runs|   2|    100000|     100|0.89128426|  PASSED
102:           sts_serial|   1|    100000|     100|0.76618520|  PASSED
102:           sts_serial|   2|    100000|     100|0.51804588|  PASSED
102:           sts_serial|   3|    100000|     100|0.54076681|  PASSED
102:           sts_serial|   3|    100000|     100|0.51414389|  PASSED
102:           sts_serial|   4|    100000|     100|0.18600760|  PASSED
102:           sts_serial|   4|    100000|     100|0.22984905|  PASSED
102:           sts_serial|   5|    100000|     100|0.25883020|  PASSED
102:           sts_serial|   5|    100000|     100|0.99315299|  PASSED
102:           sts_serial|   6|    100000|     100|0.40048642|  PASSED
102:           sts_serial|   6|    100000|     100|0.73022511|  PASSED
102:           sts_serial|   7|    100000|     100|0.79035813|  PASSED
102:           sts_serial|   7|    100000|     100|0.91930371|  PASSED
102:           sts_serial|   8|    100000|     100|0.51635740|  PASSED
102:           sts_serial|   8|    100000|     100|0.87010763|  PASSED
102:           sts_serial|   9|    100000|     100|0.95493347|  PASSED
102:           sts_serial|   9|    100000|     100|0.15935465|  PASSED
102:           sts_serial|  10|    100000|     100|0.32276697|  PASSED
102:           sts_serial|  10|    100000|     100|0.67645664|  PASSED
102:           sts_serial|  11|    100000|     100|0.64714937|  PASSED
102:           sts_serial|  11|    100000|     100|0.83931114|  PASSED
102:           sts_serial|  12|    100000|     100|0.98898429|  PASSED
102:           sts_serial|  12|    100000|     100|0.98306183|  PASSED
102:           sts_serial|  13|    100000|     100|0.73353342|  PASSED
102:           sts_serial|  13|    100000|     100|0.75717141|  PASSED
102:           sts_serial|  14|    100000|     100|0.18283051|  PASSED
102:           sts_serial|  14|    100000|     100|0.52874060|  PASSED
102:           sts_serial|  15|    100000|     100|0.35740156|  PASSED
102:           sts_serial|  15|    100000|     100|0.83391413|  PASSED
102:           sts_serial|  16|    100000|     100|0.61391208|  PASSED
102:           sts_serial|  16|    100000|     100|0.83537094|  PASSED
201: rgb_minimum_distance|   0|     10000|    1000|0.00000000|  FAILED
202:     rgb_permutations|   5|    100000|     100|0.85828591|  PASSED
203:       rgb_lagged_sum|   0|   1000000|     100|0.84986413|  PASSED
204:      rgb_kstest_test|   0|     10000|    1000|0.25942548|  PASSED
206:              dab_dct| 256|     50000|       1|0.62442278|  PASSED
207:         dab_filltree|  32|  15000000|       1|0.39920277|  PASSED
207:         dab_filltree|  32|  15000000|       1|0.57982406|  PASSED
208:        dab_filltree2|   0|   5000000|       1|0.90094772|  PASSED
208:        dab_filltree2|   1|   5000000|       1|0.58950861|  PASSED
209:         dab_monobit2|  12|  65000000|       1|0.94848945|  PASSED
 201 - , . :
cat /dev/urandom | dieharder -g 200 -d 201
, :
cat /dev/urandom | dieharder -g 200 -a
:
rgb_minimum_distance|   2|     10000|    1000|0.20617106|  PASSED
rgb_minimum_distance|   3|     10000|    1000|0.00275459|   WEAK
rgb_minimum_distance|   4|     10000|    1000|0.47683577|  PASSED
rgb_minimum_distance|   5|     10000|    1000|0.92418653|  PASSED
dieharder, p-value (P-). , [0, 1] . ≤ 0.01 ≥ 0.99 1% , [0.3, 0.4) 10% . 0 1, .
FIPS , ( 1:1250), , rngd . , , , , , .
Updated: 1324 /, :
rngtest ( )rngtest: bits received from input: 724458496
rngtest: FIPS 140-2 successes: 36199
rngtest: FIPS 140-2 failures: 23
rngtest: FIPS 140-2(2001-10-10) Monobit: 2
rngtest: FIPS 140-2(2001-10-10) Poker: 2
rngtest: FIPS 140-2(2001-10-10) Runs: 10
rngtest: FIPS 140-2(2001-10-10) Long run: 9
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
 , . (acceptable_fault). , (threshold), , threshold. .
AtmelStudio Tools → External Tools...:
Title: Deploy
Command: D:\UTILS\avrdude\avrdude.exe
Arguments: -CD:\UTILS\avrdude\avrdude.conf -v -patmega328p -carduino -PCOM5 -b113636 -D -Uflash:w:"$(BinDir)\$(TargetName).hex":i
Use Output window ()
USB-UART . 113636, . , $(BinDir), , , wrn .
, : wrn_atmega328p_20MHz.hex. USB-UART Linux :
avrdude -C/etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyUSB0 -b113636 -D -Uflash:w:"wrn_atmega328p_20MHz.hex":i
, RS232, , , , DTR :
wrnctrl flash wrn_atmega328p_20MHz.hex
اقرأ المزيد عن برنامج خادم Linux في المقالة التالية المتاحة على Habrahabr على: الجزء 2 (الخادم) .