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/ Amforth-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/amforth-devel