Hi Alaric,
On 06/19/2012 10:25 PM, Alaric Snell-Pym wrote:
>>> I plan to customise it a bit (I've written up a bunch of portpin:
>>> >> declarations that match the arduino pin names, and I'm working on
>>> >> adapting the demonstration PWM and ADC code from lib/ into something
>>> >> that,
>> >
>> > Erich has written a lot of code for the danger shield. Maybe you
>> > two could collaborate?
> Sounds good to me!
>
I have used the code below to run a simple test script on newly assembled
danger shields. Missing parts and/or known "bad" code"
a. not properly debouncing the switches
b. the menu logic
c. I have not bothered to properly convert the temperature sensor readings
into Celsius or so. Please note that the connection details of this sensor
have changed between board revisions!
Have the appropriate amount of fun.
Erich
-----------------------------------------------------------------------------------
\ 2011-03-06 EW
\ test arduino duemilanove + danger shield rev. 14
\ 2012-02-15 EW changed for dangershield rev. 16
\ hw layout
\ arduino | atmega328p | danger shield
\ D0 | PD0 rx |
\ D1 | PD1 tx |
\ D2 | PD2 int0 |
\ D3 | PD3 int1 oc2b | bz (buzzer)
\ D4 | PD4 t0 | sr_in (shift register DS)
\ D5 | PD5 t1 oc0b | led1
\ D6 | PD6 oc0a | led2
\ D7 | PD7 | sr_latch (shift register /OE)
\ |
\ D8 | PB0 icp | sr_clk (shift register SH_CP)
\ D9 | PB1 oc1a |
\ D10 | PB2 /ss oc1b | sw1 (switch)
\ D11 | PB3 mosi oc2a | sw2 (switch)
\ D12 | PB4 miso | sw3 (switch)
\ D13 | PB5 sck |
\ |
\ A0 | PC0 adc0 | sl3 (slider)
\ A1 | PC1 adc1 | sl2 (slider)
\ A2 | PC2 adc2 | sl1 (slider)
\ A3 | PC3 adc3 | light (photo cell)
\ A4 | PC4 adc4 scl | temp (temperature)
\ A5 | PC5 adc5 sda |
\ make marker
marker --start--
decimal
PORTB 2 portpin: sw1
PORTB 3 portpin: sw2
PORTB 4 portpin: sw3
PORTD 5 portpin: led1
PORTD 6 portpin: led2
PORTD 3 portpin: bz
PORTC 2 portpin: sl1
PORTC 1 portpin: sl2
PORTC 0 portpin: sl3
PORTC 3 portpin: photocell
PORTC 4 portpin: thermometer
PORTD 4 portpin: sr_in
PORTD 7 portpin: sr_oe \ output enable
PORTB 0 portpin: sr_cl
variable 1delay 20 1delay !
: msg_quit
." press switch 1 (D10) to quit" cr
;
\ --- switches -----------------------------------------------
: sw1? ( -- true|false )
sw1 pin_low? if \ if switch1 pressed
&20 ms \ { wait a little
sw1 pin_low? if \ if switch1 still pressed
-1 \ { "true" on stack
else \ }else
0 \ { "false on stack
then \ }
else \ }else
0 \ { "false" on stack
then \ }
;
\ --- buzzer -------------------------------------------------
\ 2 ms T_period =^= 500 Hz
: buzz ( cycles -- )
0 ?do bz low 1ms bz high 1ms loop
;
\ --- analog digital converter -------------------------------
\ --- adc ---
: or! dup c@ rot or swap c! ;
\ pin>pos
\ convert bitmask of portpin: back to value (bitposition)
: pin>pos ( pinmask portaddr -- pos )
drop ( -- pinmask )
log2 ( -- pos_of_most_significant_bit )
;
: adc.init ( -- )
\ ADMUX
\ A_ref is NOT connected externally
\ ==> need to set bit REFS0 in register ADMUX
[ 1 5 lshift \ ADLAR
1 6 lshift or \ REFS0
] literal ADMUX c!
\ ADCSRA
[ 1 7 lshift \ ADEN ADC enabled
1 2 lshift or \ ADPS2 prescaler = 128
1 1 lshift or \ ADPS1 .
1 or \ ADPS0 .
] literal ADCSRA c!
;
: adc.init.pin ( bitmask portaddr -- )
over over high
pin_input
;
1 6 lshift constant ADSC_MSK \ ADStartConversion bitmask
: adc.start
\ start conversion
ADSC_MSK ADCSRA or!
;
: adc.wait
\ wait for completion of conversion
begin
ADCSRA c@ ADSC_MSK and 0=
until
;
: adc.channel! ( channel -- )
7 and \ clip channel to 0..7
ADMUX c@ 7 invert and \ read ADMUX, clear old channel
or \ add new channel
ADMUX c! \ write
;
: adc.get10 ( channel -- a )
adc.channel! adc.start adc.wait
\ 10 bit
ADCL c@
ADCH c@ 8 lshift + 6 rshift
;
: adc.get ( channel -- a )
adc.channel! adc.start adc.wait
\ 8 bit
ADCH c@
;
\ --- shift register -----------------------------------------
: bit>sr ( bit -- )
if sr_in high else sr_in low then
sr_cl high noop sr_cl low noop
;
: get.bit ( byte pos -- bit )
1 swap lshift \ -- byte bitmask
and \ -- bit
;
\ clock one byte out, MSB first!
: byte>sr ( byte -- )
8 0 do
dup 7 i - \ 7 6 5 ... 0: MSB first!
get.bit
bit>sr
loop
drop
;
: >7seg
invert
byte>sr
sr_oe low noop sr_oe high
;
create HexDigits
$3f , \ 0
$06 , \ 1
$5b , \ 2
$4f , \ 3
$66 , \ 4
$6d , \ 5
$7d , \ 6
$07 , \ 7
$7f , \ 8
$6f , \ 9
$77 , \ A
$7c , \ b
$58 , \ c
$5e , \ d
$79 , \ E
$71 , \ F
$80 constant dec.point
: emit.7seg ( n -- )
dup 0 $F within if
HexDigits + @i >7seg
else
drop
then
;
\ --- convert thermometer reading --------------------------
: .T
thermometer pin>pos adc.get10 . cr
;
\ --- test functions ---------------------------------------
: test_switches
." press switch 2,3 to light up led 1,2" cr
msg_quit
begin
sw2 pin_low? if led1 high else led1 low then
sw3 pin_low? if led2 high else led2 low then
sw1? until
;
: test_buzzer
." press switch 2 (D11) to test buzzer" cr
msg_quit
begin
sw2 pin_low? if 500 buzz then
sw1? until
;
: test_sliders
." move sliders" cr
msg_quit
begin
sl1 pin>pos adc.get 4 u0.r space space
sl2 pin>pos adc.get 4 u0.r space space
sl3 pin>pos adc.get 4 u0.r $0d emit
1delay @ ms
sw1? until
cr
;
: test_photocell
." light/shadow photocell" cr
msg_quit
begin
photocell pin>pos adc.get 4 u0.r $0d emit
1delay @ ms
sw1? until
cr
;
: test_thermometer
." warm/cool thermometer" cr
msg_quit
begin
thermometer pin>pos adc.get10 4 u0.r $0d emit
1delay @ ms
sw1? until
cr
;
: test_bits.7seg
8 0 do
1 i lshift >7seg
500 ms
loop
;
: test_emit.7seg
$10 0 do
i emit.7seg
500 ms
loop
;
: test_7seg
." show single segments on 7seg" cr
test_bits.7seg
1000 ms
." show hex numbers on 7seg" cr
test_emit.7seg
1000 ms
;
\ --- main: init, run --------------------------------------
: init
led1 pin_output
led2 pin_output
bz pin_output
\ set pins to high (internal pullup)
sw1 high sw1 pin_input
sw2 high sw2 pin_input
sw3 high sw3 pin_input
adc.init
sl1 adc.init.pin
sl2 adc.init.pin
sl3 adc.init.pin
photocell adc.init.pin
thermometer adc.init.pin
sr_in high sr_in pin_output
sr_oe high sr_oe pin_output
sr_cl low sr_cl pin_output
$ff >7seg
;
\ --- pwm: timer/counter0, led1,2 ---
\ D5 | PD5 t1 oc0b | led1
\ D6 | PD6 oc0a | led2
\ timer/counter0
\ fast pwm mode
\ TCCR0A bits
\ . COM0A[1,0] = 1,0 (non inverted mode)
\ . COM0B[1,0] = 1,0 (non inverted mode)
\ . WGM0[1,0] = 1,1 (mode3: fast pwm)
\ TCCR0B bits
\ . CS[2,1,0] = 0,1,1 (clk_io/64)
\ TIMSK0 TIFR0 TCNT0 TCCR0B TCCR0A OCR0B OCR0A
: pwm.leds.init
0 TCNT0 c! \ clear counter
led1 high led1 pin_output
led2 high led2 pin_output
\ TCCR0A = COM0A1 | COM0B1 | WGM01 | WGM00
%10100011 TCCR0A c!
\ TCCR0B = CS1 | CS0
%00000011 TCCR0B c!
;
\ control brightness via registers
\ OCR0A (D6)
\ OCR0B (D5)
: pwm.leds.off
led1 low led2 low
0 TCCR0A c!
0 TCCR0B c!
0 OCR0A c!
0 OCR0B c!
0 TCNT0 c!
;
: test_leds_pwm_slider
." move sliders to control leds (pwm)" cr
msg_quit
pwm.leds.init
begin
sl1 pin>pos adc.get 5 - 0 max OCR0B c!
sl2 pin>pos adc.get 5 - 0 max OCR0A c!
1ms
sw1? until
pwm.leds.off
cr
;
\ --- pwm: timer/counter2, buzzer ---
\ D3 | PD3 int1 oc2b | bz
\ timer/counter2
\ clear timer on compare match, ctc mode
\ TCCR2A bits
\ . COM2B[1,0] = 0,1 (non inverted mode)
\ . WGM2[1,0] = 1,0 (mode2: ctc)
\ TCCR2B bits
\ . CS[2,1,0] = 1,1,1 (clk_t2s/256)
\ TIMSK0 TIFR0 TCNT0 TCCR0B TCCR0A OCR0B OCR0A
: pwm.bz.init
0 TCNT2 c! \ clear counter
bz high bz pin_output
\ TCCR2A = COM0B0 | WGM01
%00010010 TCCR2A c!
\ TCCR2B = CS1 | CS0
%00000110 TCCR2B c!
;
\ control frequency via register
\ OCR2A
: pwm.bz.off
0 TCNT2 c!
0 TCCR2A c!
0 TCCR2B c!
0 OCR2A c!
0 OCR2B c!
;
: buzzer_pwm_once
pwm.bz.init
$20 OCR2A c! 200 ms
$30 OCR2A c! 200 ms
$40 OCR2A c! 200 ms
$0 OCR2A c! 200 ms
;
: test_buzzer_pwm
." press switch 2 (D11) to test buzzer (pwm)" cr
msg_quit
begin
sw2 pin_low? if 500 buzzer_pwm_once then
sw1? until
pwm.bz.off
;
: test_bz_pwm_slider
." move slider1 to control buzzer (pwm)" cr
msg_quit
pwm.bz.init
begin
sl1 pin>pos adc.get 5 - 0 max OCR2A c!
1ms
sw1? until
pwm.bz.off
cr
;
\ --- --- ---
variable state
9 constant max_state
: run
init
0 state !
20 1delay !
." press switch 1 (D10) for next test" cr
begin
sw1? if
state @ 1+
dup max_state > if drop 0 then
dup state !
. cr
then
\ state @ 0 = ( do nothing )
state @ 1 = if test_switches then
state @ 2 = if test_buzzer then
state @ 3 = if test_buzzer_pwm then
state @ 4 = if test_sliders then
state @ 5 = if test_leds_pwm_slider then
state @ 6 = if test_photocell then
state @ 7 = if test_thermometer then
state @ 8 = if test_7seg 1 state +! then
\ wait some
1delay @ 5 * ms
key? until
key drop
;
\ fin
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Amforth-devel mailing list for http://amforth.sf.net/
[email protected]
https://lists.sourceforge.net/lists/listinfo/amforth-devel