Heb je wel de gnd van de LED-strip verbonden met de gnd van de rest?
[ Voor 3% gewijzigd door DurkVell op 10-07-2018 12:49 ]
[ Voor 3% gewijzigd door DurkVell op 10-07-2018 12:49 ]
[ Voor 48% gewijzigd door SToRM666 op 10-07-2018 14:01 ]
PSN id: NL_SToRM
Dat maakt het misschien wel wat duidelijker!
[ Voor 18% gewijzigd door DurkVell op 10-07-2018 14:18 ]
[ Voor 54% gewijzigd door SToRM666 op 11-07-2018 09:31 ]
PSN id: NL_SToRM
Ik heb een strip van 5 meter met 60 leds per meter. Ik ben van plan om hiervan 1.5 a 2 meter te gebruiken, wat volgens berekeningen op een theoretische 6A max uit zou komen (120*50mA) bij 2 meter. Ik heb voor de ledstrip een aparte voeding van 5V/6A gekocht. Ik zit ook nog te overwegen om een aluminium profiel te bestellen om zo het licht wat meer diffuus te makenComestus schreef op woensdag 11 juli 2018 @ 10:49:
Hey Storm,
Heb het ongeveer gebouwd als jij nu maakt zonder mp3 systeem. Alles zit bij mij op een 5v 3A voedingsblok, en geeft geen issues. Alles vol open zetten lukt niet met 144 leds/m en 1.5 meter strip, dus even meten wat je max kan sturen.
De GNDs zou ik wel even met elkaar verbinden, dat kan wellicht onverklaarbare dingen oplossen.
Goeie tip, die heb ik volgens mij wel liggen, ik heb namelijk een kit van amazon besteld waar al een heleboel in zat. Er is nu ook een shield onderweg met 5 knoppen erop (deze), welke maar 1 analoge uitgang heeft. Dat gaat ook behoorlijk wat aansluitingen besparen.Voor de controlls heb ik een rotary encoder gebruikt, dit is een draaiknop met drukknop in een. Zo krijg je een wat cleaner design, en houd je wat io pinnen over.
Bedankt! Ik ben wel benieuwd naar wat foto's van jouw projectVolgende leuke stap is misschien een esp8266 eraan knopen en dan de tijd via internet ophalen en doorsturen naar je arduino.
Succes.
[ Voor 3% gewijzigd door SToRM666 op 13-07-2018 09:00 ]
PSN id: NL_SToRM
Als knop1 ingedrukt wordt, ga je Led1 inschakelen.MartijnV03 schreef op vrijdag 6 juli 2018 @ 15:26:
De led's gaan aan wanneer het moet, maar wanneer beide toetsen ingedrukt worden dan moeten eigenlijk led1 en led2 uitgaan.
code:
1 2 3 4 5 6 7 //als buton1 ingedrukt is, led1 aan //andere leds uit if (buttonState1 == HIGH) { digitalWrite(ledPin1, HIGH); } else { digitalWrite(ledPin1, LOW); }
1
2
3
4
5
6
| if (buttonState1 == HIGH) { digitalWrite(ledPin1, HIGH); digitalWrite(ledPin2, LOW); } else { digitalWrite(ledPin1, LOW); } |
[ Voor 20% gewijzigd door SToRM666 op 14-07-2018 17:33 ]
PSN id: NL_SToRM
Als je de - draden allemaal in dezelfde connector stopt, dan is het al goedSToRM666 schreef op zaterdag 14 juli 2018 @ 12:28:
Dus 3 (+) draden en 3 (-) en dan nog eens apart aarding van de ledstrip en mp3 naar de Arduino.
[ Voor 4% gewijzigd door Raven op 14-07-2018 14:17 ]
After the first glass you see things as you wish they were. After the second you see things as they are not. Finally you see things as they really are, and that is the most horrible thing in the world...
Oscar Wilde
[ Voor 27% gewijzigd door SToRM666 op 14-07-2018 14:51 ]
PSN id: NL_SToRM
After the first glass you see things as you wish they were. After the second you see things as they are not. Finally you see things as they really are, and that is the most horrible thing in the world...
Oscar Wilde
[ Voor 11% gewijzigd door SToRM666 op 14-07-2018 17:37 ]
PSN id: NL_SToRM
[ Voor 15% gewijzigd door SToRM666 op 16-07-2018 10:26 ]
PSN id: NL_SToRM
PSN id: NL_SToRM
PSN id: NL_SToRM
Kijk maar eens op mysensors.org voor inspiratie. Staan leuke voorbeelden op in lijn met jouw ideeen. Fijne vakantie toegewenstPowerblast schreef op maandag 16 juli 2018 @ 20:27:
Ik heb de komende tijd wat vakantie gepland staan en dat lijkt me het ideale moment om m'n oude arduino eens vanonder het stof te halen en eens aan m'n eerste grotere projectje te beginnen. Ben nooit echt verder dan wat sensors uitlezen geraakt wegens m'n gebrek aan elektronica kennis, maar hoop daar gaandeweg verandering in te brengen.
Nu heb ik natuurlijk wel wat vragen waar ik als beginner maar lastig uit geraakt, ik hoop dus dat jullie me wat op weg kunnen helpen.
Ik wil een soort van garden monitoring systeempje in elkaar zetten. Ik wil dus starten met eerst via sensoren de temperatuur en de vochtigheid van de grond uit te lezen. Dat zou dan doorgestuurd worden naar een java applicatie die ik draaiende heb op een raspberry pi en via http wil bereiken. De raspberry pi wordt dus de command unit zeg maar zodat ik naar de toekomst toe nog kan uitbreiden. Aan deze raspberry pi koppel ik een arduino mkr (omdat deze wifi aankan) of iets dergelijks om de sensoren aan te sturen.
Maar nu vraag ik me af hoe ik de sensoren het beste bouw. Ik wil ze graag draadloos maken zodat ik ze gemakkelijk kan verplaatsen indien nodig. Ik dacht zelf aan zo van die nrf24l01 modules om draadloos commando's heen en weer te sturen. Als ik het goed zo heb ik per sensor dan wel nog iets van en arduino achtig boardje nodig. Welke zijn daar het meest geschikt voor? Om nu overal een arduino uno aan te koppel lijkt me wel wat overkill en vooral vrij prijzigomdat het uiteindelijk maar wat dummy sensoren zijn. Zijn nano/micro of iets anders daar ook geschikt voor (al dan niet clone?)
Jullie mening is meer dan welkom
Haha, die vakantie zal wel lukkentsjoender schreef op maandag 16 juli 2018 @ 20:33:
[...]
Kijk maar eens op mysensors.org voor inspiratie. Staan leuke voorbeelden op in lijn met jouw ideeen. Fijne vakantie toegewenst
Powerblast schreef op maandag 16 juli 2018 @ 20:27:
... heel verhaal ...
Kijk eens naar de hier uitgebreid besproken ESP8266!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
| #include <WaveHC.h> #include <WaveUtil.h> SdReader card; FatVolume vol; FatReader root; FatReader file; WaveHC wave; #define error(msg) error_P(PSTR(msg)) #define ADC_CHANNEL 0 #define DAC_CS_PORT PORTD #define DAC_CS PORTD2 #define DAC_CLK_PORT PORTD #define DAC_CLK PORTD3 #define DAC_DI_PORT PORTD #define DAC_DI PORTD4 #define DAC_LATCH_PORT PORTD #define DAC_LATCH PORTD5 uint16_t in = 0, out = 0, xf = 0, nSamples; uint8_t adc_save; extern uint8_t buffer1[PLAYBUFFLEN], buffer2[PLAYBUFFLEN]; #define XFADE 16 #define MAX_SAMPLES (PLAYBUFFLEN - XFADE) ///////////////////// SETUP void setup() { uint8_t i; Serial.begin(9600); pinMode(2, OUTPUT); // Chip select pinMode(3, OUTPUT); // Serial clock pinMode(4, OUTPUT); // Serial data pinMode(5, OUTPUT); // Latch digitalWrite(2, HIGH); // Set chip select high if(!card.init()) SerialPrint_P("Card init. failed!"); else if(!vol.init(card)) SerialPrint_P("No partition!"); else if(!root.openRoot(vol)) SerialPrint_P("Couldn't open dir"); else { PgmPrintln("Files found:"); root.ls(); // Play startup sound (last file in array). playfile(sizeof(sound) / sizeof(sound[0]) - 1); } TIMSK0 = 0; // Set up Analog-to-Digital converter: analogReference(EXTERNAL); // 3.3V to AREF adc_save = ADCSRA; // Save ADC setting for restore later // Set keypad rows to outputs, set to HIGH logic level: for(i=0; i<sizeof(rows); i++) { pinMode(rows[i], OUTPUT); digitalWrite(rows[i], HIGH); } // Set keypad columns to inputs, enable pull-up resistors: for(i=0; i<sizeof(cols); i++) { pinMode(cols[i], INPUT); digitalWrite(cols[i], HIGH); } while(wave.isplaying); // Wait for startup sound to finish... startWrench(); // and start the pitch-shift mode by default. } //////////////////////////////////// LOOP void loop() { uint8_t c, button; // Set current row to LOW logic state... digitalWrite(rows[r], LOW); // ...then examine column buttons for a match... for(c=0; c<sizeof(cols); c++) { if(digitalRead(cols[c]) == LOW) { // First match. button = r * sizeof(cols) + c; // Get button index. if(button == prev) { // Same button as before? if(++count >= DEBOUNCE) { // Yes. Held beyond debounce threshold? if(wave.isplaying) wave.stop(); // Stop current WAV (if any) else stopWrench(); // or stop voice effect playfile(button); // and play new sound. while(digitalRead(cols[c]) == LOW); // Wait for button release. prev = 255; // Reset debounce values. count = 0; } } else { // Not same button as prior pass. prev = button; // Record new button and count = 0; // restart debounce counter. } } } // Restore current row to HIGH logic state and advance row counter... digitalWrite(rows[r], HIGH); if(++r >= sizeof(rows)) { // If last row scanned... r = 0; // Reset row counter // If no new sounds have been triggered at this point, and if the // pitch-shifter is not running, re-start it... if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startWrench(); } } //////////////////////////////////// HELPERS // Open and start playing a WAV file void playfile(int idx) { char filename[13]; (void)sprintf(filename,"%s.wav", sound[idx]); Serial.print("File: "); Serial.println(filename); if(!file.open(root, filename)) { Serial.print(F("Couldn't open file ")); Serial.print(filename); return; } if(!wave.create(file)) { Serial.println(F("Not a valid WAV")); return; } wave.play(); } //////////////////////////////////// WRENCH MODULATION CODE void startWrench() { } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
| //////////////////////////////////// DALEK MODULATION CODE void startDalek() { // Start up ADC in free-run mode for audio sampling: DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0 ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator ADCSRB = 0; // Free-run mode ADCSRA = _BV(ADEN) | // Enable ADC _BV(ADSC) | // Start conversions _BV(ADATE) | // Auto-trigger enable _BV(ADIE) | // Interrupt enable _BV(ADPS2) | // 128:1 prescale... _BV(ADPS1) | // ...yields 125 KHz ADC clock... _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz } void stopDalek() { ADCSRA = adc_save; // Disable ADC interrupt and allow normal use } // Dalek sound is produced by a 'ring modulator' which multiplies microphone // input by a 30 Hz sine wave. sin() is a time-consuming floating-point // operation so instead a canned 8-bit integer table is used...the number of // elements here takes into account the ADC sample rate (~9615 Hz) and the // desired sine wave frequency (traditionally ~30 Hz for Daleks). // This is actually abs(sin(x)) to slightly simplify some math later. volatile uint16_t ringPos = 0; // Current index into ring table below static const uint8_t PROGMEM ring[] = { 0x00, 0x03, 0x05, 0x08, 0x0A, 0x0D, 0x0F, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x1E, 0x20, 0x23, 0x25, 0x28, 0x2A, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3E, 0x40, 0x43, 0x45, 0x48, 0x4A, 0x4C, 0x4F, 0x51, 0x54, 0x56, 0x58, 0x5B, 0x5D, 0x5F, 0x62, 0x64, 0x66, 0x68, 0x6B, 0x6D, 0x6F, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7D, 0x7F, 0x81, 0x83, 0x85, 0x87, 0x89, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xA9, 0xAB, 0xAD, 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xBA, 0xBB, 0xBD, 0xBF, 0xC0, 0xC2, 0xC4, 0xC5, 0xC7, 0xC8, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD3, 0xD4, 0xD5, 0xD7, 0xD8, 0xD9, 0xDB, 0xDC, 0xDD, 0xDE, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, 0xF7, 0xF6, 0xF5, 0xF5, 0xF4, 0xF3, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 0xE7, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 0xDE, 0xDD, 0xDC, 0xDB, 0xD9, 0xD8, 0xD7, 0xD5, 0xD4, 0xD3, 0xD1, 0xD0, 0xCE, 0xCD, 0xCB, 0xCA, 0xC8, 0xC7, 0xC5, 0xC4, 0xC2, 0xC0, 0xBF, 0xBD, 0xBB, 0xBA, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF, 0xAD, 0xAB, 0xA9, 0xA8, 0xA6, 0xA4, 0xA2, 0xA0, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8E, 0x8C, 0x89, 0x87, 0x85, 0x83, 0x81, 0x7F, 0x7D, 0x7A, 0x78, 0x76, 0x74, 0x72, 0x6F, 0x6D, 0x6B, 0x68, 0x66, 0x64, 0x62, 0x5F, 0x5D, 0x5B, 0x58, 0x56, 0x54, 0x51, 0x4F, 0x4C, 0x4A, 0x48, 0x45, 0x43, 0x40, 0x3E, 0x3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2A, 0x28, 0x25, 0x23, 0x20, 0x1E, 0x1B, 0x19, 0x17, 0x14, 0x12, 0x0F, 0x0D, 0x0A, 0x08, 0x05, 0x03 }; ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete uint8_t hi, lo, bit; int32_t v; // Voice in uint16_t r; // Ring in uint32_t o; // Output lo = ADCL; hi = ADCH; // Multiply signed 10-bit input by abs(sin(30 Hz)): v = ((int32_t)hi << 8 | lo) - 512; // voice = -512 to +511 r = (uint16_t)pgm_read_byte(&ring[ringPos]) + 1; // ring = 1 to 256 o = v * r + 131072; // 0-261888 (18-bit) hi = (o >> 14); // Scale 18- to 12-bit lo = (o >> 16) | (o >> 6); if(++ringPos >= sizeof(ring)) ringPos = 0; // Cycle through table // Issue result to DAC: DAC_CS_PORT &= ~_BV(DAC_CS); DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_DI_PORT |= _BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); for(bit=0x08; bit; bit>>=1) { if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } for(bit=0x80; bit; bit>>=1) { if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } DAC_CS_PORT |= _BV(DAC_CS); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
| //////////////////////////////////// PITCH-SHIFT CODE void startPitchShift() { // Read analog pitch setting before starting audio sampling: int pitch = analogRead(1); Serial.print("Pitch: "); Serial.println(pitch); // Right now the sketch just uses a fixed sound buffer length of // 128 samples. It may be the case that the buffer length should // vary with pitch for better results...further experimentation // is required here. nSamples = 128; //nSamples = F_CPU / 3200 / OCR2A; // ??? //if(nSamples > MAX_SAMPLES) nSamples = MAX_SAMPLES; //else if(nSamples < (XFADE * 2)) nSamples = XFADE * 2; memset(buffer1, 0, nSamples + XFADE); // Clear sample buffers memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512) // WaveHC library already defines a Timer1 interrupt handler. Since we // want to use the stock library and not require a special fork, Timer2 // is used for a sample-playing interrupt here. As it's only an 8-bit // timer, a sizeable prescaler is used (32:1) to generate intervals // spanning the desired range (~4.8 KHz to ~19 KHz, or +/- 1 octave // from the sampling frequency). This does limit the available number // of speed 'steps' in between (about 79 total), but seems enough. TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20); // 32:1 prescale OCR2A = map(pitch, 0, 1023, F_CPU / 32 / (9615 / 2), // Lowest pitch = -1 octave F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave // Start up ADC in free-run mode for audio sampling: DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0 ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator ADCSRB = 0; // Free-run mode ADCSRA = _BV(ADEN) | // Enable ADC _BV(ADSC) | // Start conversions _BV(ADATE) | // Auto-trigger enable _BV(ADIE) | // Interrupt enable _BV(ADPS2) | // 128:1 prescale... _BV(ADPS1) | // ...yields 125 KHz ADC clock... _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt sei(); // Enable interrupts } void stopPitchShift() { ADCSRA = adc_save; // Disable ADC interrupt and allow normal use TIMSK2 = 0; // Disable Timer2 Interrupt } ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete // Save old sample from 'in' position to xfade buffer: buffer1[nSamples + xf] = buffer1[in]; buffer2[nSamples + xf] = buffer2[in]; if(++xf >= XFADE) xf = 0; // Store new value in sample buffers: buffer1[in] = ADCL; // MUST read ADCL first! buffer2[in] = ADCH; if(++in >= nSamples) in = 0; } ISR(TIMER2_OVF_vect) { // Playback interrupt uint16_t s; uint8_t w, inv, hi, lo, bit; int o2, i2, pos; // Cross fade around circular buffer 'seam'. if((o2 = (int)out) == (i2 = (int)in)) { // Sample positions coincide. Use cross-fade buffer data directly. pos = nSamples + xf; hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); // Expand 10-bit data lo = (buffer1[pos] << 2) | buffer2[pos]; // to 12 bits } if((o2 < i2) && (o2 > (i2 - XFADE))) { // Output sample is close to end of input samples. Cross-fade to // avoid click. The shift operations here assume that XFADE is 16; // will need adjustment if that changes. w = in - out; // Weight of sample (1-n) inv = XFADE - w; // Weight of xfade pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; // Shift 14 bit result lo = s >> 2; // down to 12 bits } else if (o2 > (i2 + nSamples - XFADE)) { // More cross-fade condition w = in + nSamples - out; inv = XFADE - w; pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; // Shift 14 bit result lo = s >> 2; // down to 12 bits } else { // Input and output counters don't coincide -- just use sample directly. hi = (buffer2[out] << 2) | (buffer1[out] >> 6); // Expand 10-bit data lo = (buffer1[out] << 2) | buffer2[out]; // to 12 bits } // Might be possible to tweak 'hi' and 'lo' at this point to achieve // different voice modulations -- robot effect, etc.? DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC // Clock out 4 bits DAC config (not in loop because it's constant) DAC_DI_PORT &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_DI_PORT |= _BV(DAC_DI); // 1X gain, enable = 1 DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } DAC_CS_PORT |= _BV(DAC_CS); // Unselect DAC if(++out >= nSamples) out = 0; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| Arduino: 1.8.5 (Mac OS X), Board: "Arduino/Genuino Uno" /Users/User/Desktop/adavoice_wrench/adavoice_wrench.ino: In function 'void setup()': adavoice_wrench:59: error: 'startWrench' was not declared in this scope startWrench(); // and start the pitch-shift mode by default. ^ /Users/User/Desktop/adavoice_wrench/adavoice_wrench.ino:33:11: warning: unused variable 'i' [-Wunused-variable] uint8_t i; ^ /Users/User/Desktop/adavoice_wrench/adavoice_wrench.ino: In function 'void loop()': adavoice_wrench:68: error: 'rows' was not declared in this scope digitalWrite(rows[r], LOW); ^ adavoice_wrench:68: error: 'r' was not declared in this scope digitalWrite(rows[r], LOW); ^ adavoice_wrench:70: error: 'cols' was not declared in this scope for(c=0; c<sizeof(cols); c++) { ^ adavoice_wrench:73: error: 'prev' was not declared in this scope if(button == prev) { // Same button as before? ^ adavoice_wrench:74: error: 'count' was not declared in this scope if(++count >= DEBOUNCE) { // Yes. Held beyond debounce threshold? ^ adavoice_wrench:74: error: 'DEBOUNCE' was not declared in this scope if(++count >= DEBOUNCE) { // Yes. Held beyond debounce threshold? ^ adavoice_wrench:76: error: 'stopWrench' was not declared in this scope else stopWrench(); // or stop voice effect ^ adavoice_wrench:77: error: 'playfile' was not declared in this scope playfile(button); // and play new sound. ^ adavoice_wrench:84: error: 'count' was not declared in this scope count = 0; // restart debounce counter. ^ adavoice_wrench:90: error: too few arguments to function 'void digitalWrite(uint8_t, uint8_t)' digitalWrite( HIGH); ^ In file included from sketch/adavoice_wrench.ino.cpp:1:0: /Users/User/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/Arduino.h:134:6: note: declared here void digitalWrite(uint8_t, uint8_t); ^ adavoice_wrench:91: error: 'startWrench' was not declared in this scope if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startWrench(); ^ /Users/User/Desktop/adavoice_wrench/adavoice_wrench.ino: At global scope: adavoice_wrench:93: error: expected declaration before '}' token } ^ exit status 1 'startWrench' was not declared in this scope This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
| #include <WaveHC.h> #include <WaveUtil.h> SdReader card; FatVolume vol; FatReader root; FatReader file; WaveHC wave; #define error(msg) error_P(PSTR(msg)) #define ADC_CHANNEL 0 #define DAC_CS_PORT PORTD #define DAC_CS PORTD2 #define DAC_CLK_PORT PORTD #define DAC_CLK PORTD3 #define DAC_DI_PORT PORTD #define DAC_DI PORTD4 #define DAC_LATCH_PORT PORTD #define DAC_LATCH PORTD5 uint16_t in = 0, out = 0, xf = 0, nSamples; uint8_t adc_save; extern uint8_t buffer1[PLAYBUFFLEN], buffer2[PLAYBUFFLEN]; #define XFADE 16 #define MAX_SAMPLES (PLAYBUFFLEN - XFADE) ///////////////////// SETUP void setup() { uint8_t i; Serial.begin(9600); pinMode(2, OUTPUT); // Chip select pinMode(3, OUTPUT); // Serial clock pinMode(4, OUTPUT); // Serial data pinMode(5, OUTPUT); // Latch digitalWrite(2, HIGH); // Set chip select high if(!card.init()) SerialPrint_P("Card init. failed!"); else if(!vol.init(card)) SerialPrint_P("No partition!"); else if(!root.openRoot(vol)) SerialPrint_P("Couldn't open dir"); else { PgmPrintln("Files found:"); root.ls(); } TIMSK0 = 0; // Set up Analog-to-Digital converter: analogReference(EXTERNAL); // 3.3V to AREF adc_save = ADCSRA; // Save ADC setting for restore later while(wave.isplaying); // Wait for startup sound to finish... startWrench(); // and start the pitch-shift mode by default. } //////////////////////////////////// LOOP void loop() { uint8_t c, button; // Set current row to LOW logic state... digitalWrite(rows[r], LOW); // ...then examine column buttons for a match... for(c=0; c<sizeof(cols); c++) { if(digitalRead(cols[c]) == LOW) { // First match. button = r * sizeof(cols) + c; // Get button index. if(button == prev) { // Same button as before? if(++count >= DEBOUNCE) { // Yes. Held beyond debounce threshold? if(wave.isplaying) wave.stop(); // Stop current WAV (if any) else stopWrench(); // or stop voice effect playfile(button); // and play new sound. while(digitalRead(cols[c]) == LOW); // Wait for button release. prev = 255; // Reset debounce values. count = 0; } } else { // Not same button as prior pass. prev = button; // Record new button and count = 0; // restart debounce counter. } } } // Restore current row to HIGH logic state and advance row counter... digitalWrite( HIGH); if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startWrench(); } } //////////////////////////////////// WRENCH MODULATION CODE void startWrench() { // Read analog pitch setting before starting audio sampling: int pitch = analogRead(1); Serial.print("Pitch: "); Serial.println(pitch); nSamples = 128; memset(buffer1, 0, nSamples + XFADE); // Clear sample buffers memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512) TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20); // 32:1 prescale OCR2A = map(pitch, 0, 1023, F_CPU / 32 / (9615 / 2), // Lowest pitch = -1 octave F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0 ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator ADCSRB = 0; // Free-run mode ADCSRA = _BV(ADEN) | // Enable ADC _BV(ADSC) | // Start conversions _BV(ADATE) | // Auto-trigger enable _BV(ADIE) | // Interrupt enable _BV(ADPS2) | // 128:1 prescale... _BV(ADPS1) | // ...yields 125 KHz ADC clock... _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt sei(); // Enable interrupts // Start up ADC in free-run mode for audio sampling: DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0 ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator ADCSRB = 0; // Free-run mode ADCSRA = _BV(ADEN) | // Enable ADC _BV(ADSC) | // Start conversions _BV(ADATE) | // Auto-trigger enable _BV(ADIE) | // Interrupt enable _BV(ADPS2) | // 128:1 prescale... _BV(ADPS1) | // ...yields 125 KHz ADC clock... _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz } void stopWrench() { ADCSRA = adc_save; // Disable ADC interrupt and allow normal use TIMSK2 = 0; // Disable Timer2 Interrupt } volatile uint16_t ringPos = 0; // Current index into ring table below static const uint8_t PROGMEM ring[] = { 0x00, 0x03, 0x05, 0x08, 0x0A, 0x0D, 0x0F, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x1E, 0x20, 0x23, 0x25, 0x28, 0x2A, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3E, 0x40, 0x43, 0x45, 0x48, 0x4A, 0x4C, 0x4F, 0x51, 0x54, 0x56, 0x58, 0x5B, 0x5D, 0x5F, 0x62, 0x64, 0x66, 0x68, 0x6B, 0x6D, 0x6F, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7D, 0x7F, 0x81, 0x83, 0x85, 0x87, 0x89, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xA9, 0xAB, 0xAD, 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xBA, 0xBB, 0xBD, 0xBF, 0xC0, 0xC2, 0xC4, 0xC5, 0xC7, 0xC8, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD3, 0xD4, 0xD5, 0xD7, 0xD8, 0xD9, 0xDB, 0xDC, 0xDD, 0xDE, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, 0xF7, 0xF6, 0xF5, 0xF5, 0xF4, 0xF3, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 0xE7, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 0xDE, 0xDD, 0xDC, 0xDB, 0xD9, 0xD8, 0xD7, 0xD5, 0xD4, 0xD3, 0xD1, 0xD0, 0xCE, 0xCD, 0xCB, 0xCA, 0xC8, 0xC7, 0xC5, 0xC4, 0xC2, 0xC0, 0xBF, 0xBD, 0xBB, 0xBA, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF, 0xAD, 0xAB, 0xA9, 0xA8, 0xA6, 0xA4, 0xA2, 0xA0, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8E, 0x8C, 0x89, 0x87, 0x85, 0x83, 0x81, 0x7F, 0x7D, 0x7A, 0x78, 0x76, 0x74, 0x72, 0x6F, 0x6D, 0x6B, 0x68, 0x66, 0x64, 0x62, 0x5F, 0x5D, 0x5B, 0x58, 0x56, 0x54, 0x51, 0x4F, 0x4C, 0x4A, 0x48, 0x45, 0x43, 0x40, 0x3E, 0x3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2A, 0x28, 0x25, 0x23, 0x20, 0x1E, 0x1B, 0x19, 0x17, 0x14, 0x12, 0x0F, 0x0D, 0x0A, 0x08, 0x05, 0x03 }; ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete uint8_t hi, lo, bit; int32_t v; // Voice in uint16_t r; // Ring in uint32_t o; // Output lo = ADCL; hi = ADCH; // Save old sample from 'in' position to xfade buffer: buffer1[nSamples + xf] = buffer1[in]; buffer2[nSamples + xf] = buffer2[in]; if(++xf >= XFADE) xf = 0; // Store new value in sample buffers: buffer1[in] = ADCL; // MUST read ADCL first! buffer2[in] = ADCH; if(++in >= nSamples) in = 0; } ISR(TIMER2_OVF_vect) { // Playback interrupt uint16_t s; uint8_t w, inv, hi, lo, bit; int o2, i2, pos; // Cross fade around circular buffer 'seam'. if((o2 = (int)out) == (i2 = (int)in)) { // Sample positions coincide. Use cross-fade buffer data directly. pos = nSamples + xf; hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); // Expand 10-bit data lo = (buffer1[pos] << 2) | buffer2[pos]; // to 12 bits } if((o2 < i2) && (o2 > (i2 - XFADE))) { // Output sample is close to end of input samples. Cross-fade to // avoid click. The shift operations here assume that XFADE is 16; // will need adjustment if that changes. w = in - out; // Weight of sample (1-n) inv = XFADE - w; // Weight of xfade pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; // Shift 14 bit result lo = s >> 2; // down to 12 bits } else if (o2 > (i2 + nSamples - XFADE)) { // More cross-fade condition w = in + nSamples - out; inv = XFADE - w; pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; // Shift 14 bit result lo = s >> 2; // down to 12 bits } else { // Input and output counters don't coincide -- just use sample directly. hi = (buffer2[out] << 2) | (buffer1[out] >> 6); // Expand 10-bit data lo = (buffer1[out] << 2) | buffer2[out]; // to 12 bits } // Multiply signed 10-bit input by abs(sin(30 Hz)): v = ((int32_t)hi << 8 | lo) - 512; // voice = -512 to +511 r = (uint16_t)pgm_read_byte(&ring[ringPos]) + 1; // ring = 1 to 256 o = v * r + 131072; // 0-261888 (18-bit) hi = (o >> 14); // Scale 18- to 12-bit lo = (o >> 16) | (o >> 6); if(++ringPos >= sizeof(ring)) ringPos = 0; // Cycle through table // Might be possible to tweak 'hi' and 'lo' at this point to achieve // different voice modulations -- robot effect, etc.? DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC // Clock out 4 bits DAC config (not in loop because it's constant) DAC_DI_PORT &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_DI_PORT |= _BV(DAC_DI); // 1X gain, enable = 1 DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } DAC_CS_PORT |= _BV(DAC_CS); // Unselect DAC if(++out >= nSamples) out = 0; } |
[ Voor 97% gewijzigd door solutionnl op 20-07-2018 16:07 ]
Link eens naar de library die je gebruikt (op github) en naar alle modules die je gebruikt.solutionnl schreef op vrijdag 20 juli 2018 @ 12:11:
Het komt er op neer dat ik 0,0 programmeerkennis heb, het ging er met name om of het mogelijk is.
Momenteel ben ik de code nog opnieuw aan het samenvoegen maar zodra ik hem compile post ik weer een update
De oude code heb ik lukraak gekopieerd en dat werkte vanzelfsprekend niet, ik kijk nu echt per line wat er verschilt aan code om zo hopelijk een werkend geheel te krijgen.
Oke, ik ben eindelijk klaar met de code overschrijven..
Ik heel blij compilen, en... teleurstelling!
Na twee jaar de Arduino zooi maar eens opgepakt…T.Kreeftmeijer schreef op dinsdag 27 september 2016 @ 19:28:
Ik heb een tijdje geleden een BMP 280 sensor gekocht. Ik kan er alleen geen voorbeeldcode/uitleg bij vinden. Wel voor een andere die hetzelfde doet, namelijk die van banafruit, geloof ik. Het is de volgende sensor:
[afbeelding]
en
[afbeelding]
Weet iemand er een uitleg/voorbeeld code bij? Ik ben nog niet echt handig en redelijk nieuw in arduino, ik leer veel van een voorbeeld code.
Daar ga ik (nog) eens naar kijken.chaoscontrol schreef op dinsdag 27 september 2016 @ 19:51:
Zou gewoon de Adafruit BME280 library eens proberen. Zit wel een example bij.
[ Voor 20% gewijzigd door T.Kreeftmeijer op 24-07-2018 16:56 ]
13 000 Zeemijl - documentaire - Soms maakt al die keus het er niet makkelijker op.
Wil je het connecten via I2C of via SPI? Als je het verschil niet weet, dan kies je er gewoon 1. Voor jouw applicatie maakt het niet uit. Hieronder is een goede guide.T.Kreeftmeijer schreef op dinsdag 24 juli 2018 @ 15:58:
[...]
Na twee jaar de Arduino zooi maar eens opgepakt…![]()
![]()
Ik heb in elk geval nog steeds deze GY-BME/P280 sensor voor me liggen.
Eerder had ik dus bepaald dat het een BMP280 was. Nu ben ik van mening dat het een gecombineerde BME/BMP280 is.
[...]
Daar ga ik (nog) eens naar kijken.
Update 16:27:
Ik heb deze gebruikt: https://learn.adafruit.co...sor-breakout/arduino-test. Daar kwam ik erachter dat de pinout anders is:Deze pinnen heb op de BMP280.
- VCC
- GND
- SCL
- SDA
- CSB
- SDO
Ik kwam ook deze tegen: https://community.particl...bmp280-3-3-sensor/28985/4
Als eerste snap ik dus niet hoe ik het moet aansluiten om het met het voorbeeld van de BMP280 Library werkend te krijgen……![]()
I2C is met bussen (minder IO nodig) en SPI is soort van direct. Tenminste zo heb ik dat begrepen. Maakt nu niet uit. Eerst maar eens waardes uit dat ding krijgen.Lennyz schreef op dinsdag 24 juli 2018 @ 20:41:
[...]
Wil je het connecten via I2C of via SPI? Als je het verschil niet weet, dan kies je er gewoon 1. Voor jouw applicatie maakt het niet uit.
Ik heb nu een nano met 3.3v pin. Ik ga die guide eens lezen.Hieronder is een goede guide.
https://startingelectroni...0-pressure-sensor-module/
Let er wel even op dat de sensor 3.3v is. Je geeft niet aan waarmee je hem wilt connecten, maar als je het via een Arduino Uno doet dan is dit board 5v. Dan moet je eerst even het voltage van de pins terugbrengen naar 3.3v.
1
2
3
| Temperature = 31.53 *C Pressure = 101451.63 Pa Approx altitude = -10.54 m |
1
2
3
4
5
6
7
8
| #define BMP_SCK 13 #define BMP_MISO 12 #define BMP_MOSI 11 #define BMP_CS 10 //Adafruit_BMP280 bme; // I2C Adafruit_BMP280 bme(BMP_CS); // hardware SPI //Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK); |
[ Voor 26% gewijzigd door T.Kreeftmeijer op 24-07-2018 22:05 . Reden: Gelukt! ]
13 000 Zeemijl - documentaire - Soms maakt al die keus het er niet makkelijker op.
Bedankt voor je reactie!Lennyz schreef op zaterdag 21 juli 2018 @ 07:47:
[...]
Link eens naar de library die je gebruikt (op github) en naar alle modules die je gebruikt.
Begin eerst met het samenvoegen van alle codes behalve die staan in de void setup en void loop.
Ga dan de void setup met elkaar vergelijken en samenvoegen, als laatste je void loop.
Ik ben hier inmiddels eindelijk toe geraakt, helaas werkt (nog) niet alles perfect.Joepla schreef op dinsdag 19 juni 2018 @ 11:39:
[...]
De voeding voor de SIM800 haal ik uit een 5V/2A netadapter (die overigens ook de Nano gaat voeden en wat sensoren). De Nano is zeker niet in staat om de piekstromen te leveren die de SIM800 vraagt tijdens zenden. Ik ga ervan uit dat deze GSM module zijn zendvermogen ook aanpast aan de omstandigheden, dus worst case zal hij flink stroom trekken, waardoor de spanning dipt en zullen waarschijnlijk zowel je SIM800 als je Nano geregeld herstarten. Mijn voeding is zelfs al wat krap denk ik, maar tot nu toe gaat het goed. Wellicht is het ook goed om rekening te houden met je antenneplaatsing. Als die te dicht bij je Nano of de bedrading zit, zou je wel eens wat rare effecten kunnen krijgen door inductie. Afschermen en/of afstand zijn dan de oplossing (of kleine condensatoren/ferrietkralen plaatsen, maar dan wordt het wat complexer).
Ik heb wel een functie ingebouwd die het resetlijntje 0,5 sec. laag trekt, zodra de signaalsterkte enige tijd op zijn laagst is. Ik heb gemerkt dat de SIM800 anders niet meer zelf online komt. Moet er wel bij zeggen dat de signaalsterkte bij mij thuis minimaal is en het antennetje dat ik gebruik ook erg klein is. Misschien dat hij uiteindelijk zelf er wel weer uitkomt, maar dat duurt dan langer dan een half uur ofzo.
[ Voor 3% gewijzigd door Joepla op 29-07-2018 20:30 ]
Goedendag tweakers,
Ik ben op dit moment bezig met een projectje waarbij ik led strips gebruik.
Alleen loop ik nu tegen een vaag probleem aan.
Situatie is als volgt:
Ik heb achter mn bureau een wand gemaakt met ledjes erin (YouTube: Led muur achter bureau
Echter wanneer ik nu een tweede ledstrip met 81 ledjes eraan toevoeg is er niks aan de hand. Maar wanneer ik op een eigen pin voor eigen bediening toevoeg beginnen beide leds te knipperen.
Ik dacht eerst dat dit kwam omdat er te weinig voeding dan is, dus heb aan beide uiteinden ook weer een snoertje getrokken naar de voeding maar dit lost het probleem niet op.
Het aparte vind ik dat wanneer je dus twee ledstreps op elk een eigen pin aan wilt sturen dit op treed. Wanneer ik 1 led los koppel is het probleem weer voorbij.
de volgende code gebruik ik:
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <FastLED.h> #define NUM_STRIPS 2 #define NUM_LEDS_PER_STRIP 100 byte brightness[NUM_LEDS_PER_STRIP]; // The brightness of each LED is controlled individually through this array byte hue[NUM_LEDS_PER_STRIP]; // The hue of each LED is controlled individually through this array byte startVal[NUM_LEDS_PER_STRIP]; // The startVal array helps to randomise the LED pattern byte minHue =0; // Keeps the hue within a certain range - this is the lower limit byte maxHue =80; // Keeps the hue within a certain range - this is upper limit byte maxBrightness = 255; // Limits the brightness of the LEDs CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP]; void setup() { FastLED.addLeds<WS2812B, 10,GRB>(leds[0], NUM_LEDS_PER_STRIP); //led strip FastLED.addLeds<WS2812B, 11>(leds[1], NUM_LEDS_PER_STRIP); //losse ledjes FastLED.clear(); for(int i = 0; i<NUM_LEDS_PER_STRIP; i++){ startVal[i] = random8(); hue[i] = random(minHue, maxHue); } fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB(255, 197, 143) ); // led strip voor bureauverlichting } void fadeall(int lednum) { for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { leds[lednum][i].nscale8(250); } } void loop() { //leds bureau achter (wall) for(int i = 0; i<NUM_LEDS_PER_STRIP; i++){ startVal[i]++; brightness[i] = sin8(startVal[i]); leds[1][i] = CHSV(hue[i], 255, map(brightness[i],0,255,0,maxBrightness)); if(random(1000)<100){ startVal[i] = startVal[i]+2; } if(brightness[i] <3){ hue[i] = random(minHue, maxHue); minHue++; maxHue++; } } FastLED.show(); delay(10); }
en ik gebruik de volgende led strips:
https://www.amazon.de/gp/...age_o04_s00?ie=UTF8&psc=1 (voor de plaat achter bureau
https://www.amazon.de/gp/...age_o05_s00?ie=UTF8&psc=1 (voor led strip als bureau verlichting)
en als aansturing gebruik ik:
Eelegoo uno R3
filmpje hoe het er dan uitziet:
YouTube: Leds flikkeren
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
| /* Dalek voice effect using Wave Shield. This is based on the adavoice sketch with a lot of code & comments ripped out, so see that code for more insight, parts list, etc. This sketch doesn't do any pitch bending, just the Dalek modulation...you'll need to perform your own monotone & British accent. :) This should still let you play sounds off the SD card (voice effect stops during playback), haven't tested, but worked in prior code this came from. Written by Adafruit industries, with portions adapted from the 'PiSpeakHC' sketch included with WaveHC library. */ #include <WaveHC.h> #include <WaveUtil.h> SdReader card; FatVolume vol; FatReader root; FatReader file; WaveHC wave; #define error(msg) error_P(PSTR(msg)) // Macro allows error messages in flash memory #define ADC_CHANNEL 0 // Microphone on Analog pin 0 // Wave shield DAC: digital pins 2, 3, 4, 5 #define DAC_CS_PORT PORTD #define DAC_CS PORTD2 #define DAC_CLK_PORT PORTD #define DAC_CLK PORTD3 #define DAC_DI_PORT PORTD #define DAC_DI PORTD4 #define DAC_LATCH_PORT PORTD #define DAC_LATCH PORTD5 uint16_t in = 0, out = 0, xf = 0, nSamples; // Audio sample counters uint8_t adc_save; // WaveHC didn't declare it's working buffers private or static, // so we can be sneaky and borrow the same RAM for audio sampling! extern uint8_t buffer1[PLAYBUFFLEN], // Audio sample LSB buffer2[PLAYBUFFLEN]; // Audio sample MSB #define XFADE 16 // Number of samples for cross-fade #define MAX_SAMPLES (PLAYBUFFLEN - XFADE) // Remaining available audio samples // Keypad information: uint8_t rows[] = { A2, A3, A4, A5 }, // Keypad rows connect to these pins cols[] = { 6, 7, 8 }, // Keypad columns connect to these pins r = 0, // Current row being examined prev = 255, // Previous key reading (or 255 if none) count = 0; // Counter for button debouncing #define DEBOUNCE 10 // Number of iterations before button 'takes' // Keypad/WAV information. Number of elements here should match the // number of keypad rows times the number of columns, plus one: const char *sound[] = { "breath" , "destroy", "saber" , // Row 1 = Darth Vader sounds "zilla" , "crunch" , "burp" , // Row 2 = Godzilla sounds "hithere", "smell" , "squirrel", // Row 3 = Dug the dog sounds "carhorn", "foghorn", "door" , // Row 4 = Cartoon/SFX sound "startup" }; // Extra item = boot sound //////////////////////////////////// SETUP void setup() { uint8_t i; Serial.begin(9600); pinMode(2, OUTPUT); // Chip select pinMode(3, OUTPUT); // Serial clock pinMode(4, OUTPUT); // Serial data pinMode(5, OUTPUT); // Latch digitalWrite(2, HIGH); // Set chip select high if(!card.init()) Serial.print(F("Card init. failed!")); else if(!vol.init(card)) Serial.print(F("No partition!")); else if(!root.openRoot(vol)) Serial.print(F("Couldn't open dir")); else { Serial.println(F("Files found:")); root.ls(); // Play startup sound (last file in array). playfile(sizeof(sound) / sizeof(sound[0]) - 1); } // Optional, but may make sampling and playback a little smoother: // Disable Timer0 interrupt. This means delay(), millis() etc. won't // work. Comment this out if you really, really need those functions. TIMSK0 = 0; // Set up Analog-to-Digital converter: analogReference(EXTERNAL); // 3.3V to AREF adc_save = ADCSRA; // Save ADC setting for restore later // Set keypad rows to outputs, set to HIGH logic level: for(i=0; i<sizeof(rows); i++) { pinMode(rows[i], OUTPUT); digitalWrite(rows[i], HIGH); } // Set keypad columns to inputs, enable pull-up resistors: for(i=0; i<sizeof(cols); i++) { pinMode(cols[i], INPUT); digitalWrite(cols[i], HIGH); } while(wave.isplaying); // Wait for startup sound to finish... startWrench(); // and start the Wrench effect } //////////////////////////////////// LOOP // As written here, the loop function scans a keypad to triggers sounds // (stopping and restarting the voice effect as needed). If all you need // is a couple of buttons, it may be easier to tear this out and start // over with some simple digitalRead() calls. void loop() { uint8_t c, button; // Set current row to LOW logic state... digitalWrite(rows[r], LOW); // ...then examine column buttons for a match... for(c=0; c<sizeof(cols); c++) { if(digitalRead(cols[c]) == LOW) { // First match. button = r * sizeof(cols) + c; // Get button index. if(button == prev) { // Same button as before? if(++count >= DEBOUNCE) { // Yes. Held beyond debounce threshold? if(wave.isplaying) wave.stop(); // Stop current WAV (if any) else stopDalek(); // or stop voice effect playfile(button); // and play new sound. while(digitalRead(cols[c]) == LOW); // Wait for button release. prev = 255; // Reset debounce values. count = 0; } } else { // Not same button as prior pass. prev = button; // Record new button and count = 0; // restart debounce counter. } } } // Restore current row to HIGH logic state and advance row counter... digitalWrite(rows[r], HIGH); if(++r >= sizeof(rows)) { // If last row scanned... r = 0; // Reset row counter // If no new sounds have been triggered at this point, restart Dalek... if(!wave.isplaying) startDalek(); } } //////////////////////////////////// HELPERS // Open and start playing a WAV file void playfile(int idx) { char filename[13]; (void)sprintf(filename,"%s.wav", sound[idx]); Serial.print("File: "); Serial.println(filename); if(!file.open(root, filename)) { Serial.print(F("Couldn't open file ")); Serial.print(filename); return; } if(!wave.create(file)) { Serial.println(F("Not a valid WAV")); return; } wave.play(); } //////////////////////////////////// DALEK MODULATION CODE void startDalek() { // Start up ADC in free-run mode for audio sampling: DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0 ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator ADCSRB = 0; // Free-run mode ADCSRA = _BV(ADEN) | // Enable ADC _BV(ADSC) | // Start conversions _BV(ADATE) | // Auto-trigger enable _BV(ADIE) | // Interrupt enable _BV(ADPS2) | // 128:1 prescale... _BV(ADPS1) | // ...yields 125 KHz ADC clock... _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz } void stopDalek() { ADCSRA = adc_save; // Disable ADC interrupt and allow normal use } // Dalek sound is produced by a 'ring modulator' which multiplies microphone // input by a 30 Hz sine wave. sin() is a time-consuming floating-point // operation so instead a canned 8-bit integer table is used...the number of // elements here takes into account the ADC sample rate (~9615 Hz) and the // desired sine wave frequency (traditionally ~30 Hz for Daleks). // This is actually abs(sin(x)) to slightly simplify some math later. volatile uint16_t ringPos = 0; // Current index into ring table below static const uint8_t PROGMEM ring[] = { 0x00, 0x03, 0x05, 0x08, 0x0A, 0x0D, 0x0F, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x1E, 0x20, 0x23, 0x25, 0x28, 0x2A, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3E, 0x40, 0x43, 0x45, 0x48, 0x4A, 0x4C, 0x4F, 0x51, 0x54, 0x56, 0x58, 0x5B, 0x5D, 0x5F, 0x62, 0x64, 0x66, 0x68, 0x6B, 0x6D, 0x6F, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7D, 0x7F, 0x81, 0x83, 0x85, 0x87, 0x89, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xA9, 0xAB, 0xAD, 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xBA, 0xBB, 0xBD, 0xBF, 0xC0, 0xC2, 0xC4, 0xC5, 0xC7, 0xC8, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD3, 0xD4, 0xD5, 0xD7, 0xD8, 0xD9, 0xDB, 0xDC, 0xDD, 0xDE, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, 0xF7, 0xF6, 0xF5, 0xF5, 0xF4, 0xF3, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 0xE7, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 0xDE, 0xDD, 0xDC, 0xDB, 0xD9, 0xD8, 0xD7, 0xD5, 0xD4, 0xD3, 0xD1, 0xD0, 0xCE, 0xCD, 0xCB, 0xCA, 0xC8, 0xC7, 0xC5, 0xC4, 0xC2, 0xC0, 0xBF, 0xBD, 0xBB, 0xBA, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF, 0xAD, 0xAB, 0xA9, 0xA8, 0xA6, 0xA4, 0xA2, 0xA0, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8E, 0x8C, 0x89, 0x87, 0x85, 0x83, 0x81, 0x7F, 0x7D, 0x7A, 0x78, 0x76, 0x74, 0x72, 0x6F, 0x6D, 0x6B, 0x68, 0x66, 0x64, 0x62, 0x5F, 0x5D, 0x5B, 0x58, 0x56, 0x54, 0x51, 0x4F, 0x4C, 0x4A, 0x48, 0x45, 0x43, 0x40, 0x3E, 0x3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2A, 0x28, 0x25, 0x23, 0x20, 0x1E, 0x1B, 0x19, 0x17, 0x14, 0x12, 0x0F, 0x0D, 0x0A, 0x08, 0x05, 0x03 }; ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete uint8_t hi, lo, bit; int32_t v; // Voice in uint16_t r; // Ring in uint32_t o; // Output lo = ADCL; hi = ADCH; // Multiply signed 10-bit input by abs(sin(30 Hz)): v = ((int32_t)hi << 8 | lo) - 512; // voice = -512 to +511 r = (uint16_t)pgm_read_byte(&ring[ringPos]) + 1; // ring = 1 to 256 o = v * r + 131072; // 0-261888 (18-bit) hi = (o >> 14); // Scale 18- to 12-bit lo = (o >> 16) | (o >> 6); if(++ringPos >= sizeof(ring)) ringPos = 0; // Cycle through table // Issue result to DAC: DAC_CS_PORT &= ~_BV(DAC_CS); DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_DI_PORT |= _BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); for(bit=0x08; bit; bit>>=1) { if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } for(bit=0x80; bit; bit>>=1) { if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } DAC_CS_PORT |= _BV(DAC_CS); } //////////////////////////////////// LOOP // As written here, the loop function scans a keypad to triggers sounds // (stopping and restarting the voice effect as needed). If all you need // is a couple of buttons, it may be easier to tear this out and start // over with some simple digitalRead() calls. void loop() { uint8_t c, button; // Set current row to LOW logic state... digitalWrite(rows[r], LOW); // ...then examine column buttons for a match... for(c=0; c<sizeof(cols); c++) { if(digitalRead(cols[c]) == LOW) { // First match. button = r * sizeof(cols) + c; // Get button index. if(button == prev) { // Same button as before? if(++count >= DEBOUNCE) { // Yes. Held beyond debounce threshold? if(wave.isplaying) wave.stop(); // Stop current WAV (if any) else stopWrench(); // or stop voice effect playfile(button); // and play new sound. while(digitalRead(cols[c]) == LOW); // Wait for button release. prev = 255; // Reset debounce values. count = 0; } } else { // Not same button as prior pass. prev = button; // Record new button and count = 0; // restart debounce counter. } } } // Restore current row to HIGH logic state and advance row counter... digitalWrite(rows[r], HIGH); if(++r >= sizeof(rows)) { // If last row scanned... r = 0; // Reset row counter if(!wave.isplaying) startWrench(); } } //////////////////////////////////// HELPERS // Open and start playing a WAV file void playfile(int idx) { char filename[13]; (void)sprintf(filename,"%s.wav", sound[idx]); Serial.print("File: "); Serial.println(filename); if(!file.open(root, filename)) { PgmPrint("Couldn't open file "); Serial.print(filename); return; } if(!wave.create(file)) { PgmPrintln("Not a valid WAV"); return; } wave.play(); } //////////////////////////////////// Wrench MODULATION CODE void startWrench() { // Read analog pitch setting before starting audio sampling: int pitch = analogRead(1); Serial.print("Pitch: "); Serial.println(pitch); // Right now the sketch just uses a fixed sound buffer length of // 128 samples. It may be the case that the buffer length should // vary with pitch for better results...further experimentation // is required here. nSamples = 128; //nSamples = F_CPU / 3200 / OCR2A; // ??? //if(nSamples > MAX_SAMPLES) nSamples = MAX_SAMPLES; //else if(nSamples < (XFADE * 2)) nSamples = XFADE * 2; memset(buffer1, 0, nSamples + XFADE); // Clear sample buffers memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512) // WaveHC library already defines a Timer1 interrupt handler. Since we // want to use the stock library and not require a special fork, Timer2 // is used for a sample-playing interrupt here. As it's only an 8-bit // timer, a sizeable prescaler is used (32:1) to generate intervals // spanning the desired range (~4.8 KHz to ~19 KHz, or +/- 1 octave // from the sampling frequency). This does limit the available number // of speed 'steps' in between (about 79 total), but seems enough. TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20); // 32:1 prescale OCR2A = map(pitch, 0, 1023, F_CPU / 32 / (9615 / 2), // Lowest pitch = -1 octave F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave // Start up ADC in free-run mode for audio sampling: DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0 ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator ADCSRB = 0; // Free-run mode ADCSRA = _BV(ADEN) | // Enable ADC _BV(ADSC) | // Start conversions _BV(ADATE) | // Auto-trigger enable _BV(ADIE) | // Interrupt enable _BV(ADPS2) | // 128:1 prescale... _BV(ADPS1) | // ...yields 125 KHz ADC clock... _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt sei(); // Enable interrupts } void stopWrench() { ADCSRA = adc_save; // Disable ADC interrupt and allow normal use TIMSK2 = 0; // Disable Timer2 Interrupt } volatile uint16_t ringPos = 0; // Current index into ring table below static const uint8_t PROGMEM ring[] = { 0x00, 0x03, 0x05, 0x08, 0x0A, 0x0D, 0x0F, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x1E, 0x20, 0x23, 0x25, 0x28, 0x2A, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3E, 0x40, 0x43, 0x45, 0x48, 0x4A, 0x4C, 0x4F, 0x51, 0x54, 0x56, 0x58, 0x5B, 0x5D, 0x5F, 0x62, 0x64, 0x66, 0x68, 0x6B, 0x6D, 0x6F, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7D, 0x7F, 0x81, 0x83, 0x85, 0x87, 0x89, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xA9, 0xAB, 0xAD, 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xBA, 0xBB, 0xBD, 0xBF, 0xC0, 0xC2, 0xC4, 0xC5, 0xC7, 0xC8, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD3, 0xD4, 0xD5, 0xD7, 0xD8, 0xD9, 0xDB, 0xDC, 0xDD, 0xDE, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, 0xF7, 0xF6, 0xF5, 0xF5, 0xF4, 0xF3, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 0xE7, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 0xDE, 0xDD, 0xDC, 0xDB, 0xD9, 0xD8, 0xD7, 0xD5, 0xD4, 0xD3, 0xD1, 0xD0, 0xCE, 0xCD, 0xCB, 0xCA, 0xC8, 0xC7, 0xC5, 0xC4, 0xC2, 0xC0, 0xBF, 0xBD, 0xBB, 0xBA, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF, 0xAD, 0xAB, 0xA9, 0xA8, 0xA6, 0xA4, 0xA2, 0xA0, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8E, 0x8C, 0x89, 0x87, 0x85, 0x83, 0x81, 0x7F, 0x7D, 0x7A, 0x78, 0x76, 0x74, 0x72, 0x6F, 0x6D, 0x6B, 0x68, 0x66, 0x64, 0x62, 0x5F, 0x5D, 0x5B, 0x58, 0x56, 0x54, 0x51, 0x4F, 0x4C, 0x4A, 0x48, 0x45, 0x43, 0x40, 0x3E, 0x3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2A, 0x28, 0x25, 0x23, 0x20, 0x1E, 0x1B, 0x19, 0x17, 0x14, 0x12, 0x0F, 0x0D, 0x0A, 0x08, 0x05, 0x03 }; |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete uint8_t hi, lo, bit; int32_t v; // Voice in uint16_t r; // Ring in uint32_t o; // Output lo = ADCL; hi = ADCH; // Multiply signed 10-bit input by abs(sin(30 Hz)): v = ((int32_t)hi << 8 | lo) - 512; // voice = -512 to +511 r = (uint16_t)pgm_read_byte(&ring[ringPos]) + 1; // ring = 1 to 256 o = v * r + 131072; // 0-261888 (18-bit) hi = (o >> 14); // Scale 18- to 12-bit lo = (o >> 16) | (o >> 6); if(++ringPos >= sizeof(ring)) ringPos = 0; // Cycle through table // Issue result to DAC: DAC_CS_PORT &= ~_BV(DAC_CS); DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_DI_PORT |= _BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); for(bit=0x08; bit; bit>>=1) { if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } for(bit=0x80; bit; bit>>=1) { if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } DAC_CS_PORT |= _BV(DAC_CS); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
| ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete // Save old sample from 'in' position to xfade buffer: buffer1[nSamples + xf] = buffer1[in]; buffer2[nSamples + xf] = buffer2[in]; if(++xf >= XFADE) xf = 0; // Store new value in sample buffers: buffer1[in] = ADCL; // MUST read ADCL first! buffer2[in] = ADCH; if(++in >= nSamples) in = 0; } ISR(TIMER2_OVF_vect) { // Playback interrupt uint16_t s; uint8_t w, inv, hi, lo, bit; int o2, i2, pos; // Cross fade around circular buffer 'seam'. if((o2 = (int)out) == (i2 = (int)in)) { // Sample positions coincide. Use cross-fade buffer data directly. pos = nSamples + xf; hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); // Expand 10-bit data lo = (buffer1[pos] << 2) | buffer2[pos]; // to 12 bits } if((o2 < i2) && (o2 > (i2 - XFADE))) { // Output sample is close to end of input samples. Cross-fade to // avoid click. The shift operations here assume that XFADE is 16; // will need adjustment if that changes. w = in - out; // Weight of sample (1-n) inv = XFADE - w; // Weight of xfade pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; // Shift 14 bit result lo = s >> 2; // down to 12 bits } else if (o2 > (i2 + nSamples - XFADE)) { // More cross-fade condition w = in + nSamples - out; inv = XFADE - w; pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; // Shift 14 bit result lo = s >> 2; // down to 12 bits } else { // Input and output counters don't coincide -- just use sample directly. hi = (buffer2[out] << 2) | (buffer1[out] >> 6); // Expand 10-bit data lo = (buffer1[out] << 2) | buffer2[out]; // to 12 bits } // Might be possible to tweak 'hi' and 'lo' at this point to achieve // different voice modulations -- robot effect, etc.? DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC // Clock out 4 bits DAC config (not in loop because it's constant) DAC_DI_PORT &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_DI_PORT |= _BV(DAC_DI); // 1X gain, enable = 1 DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI); else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); } DAC_CS_PORT |= _BV(DAC_CS); // Unselect DAC if(++out >= nSamples) out = 0; } |
[ Voor 78% gewijzigd door solutionnl op 31-07-2018 10:33 ]
Zoals je inmiddels achter gekomen bent is programmeren meer dan verschillende demo code aan elkaar plakken. Als je dit wilt laten werken kan je volgens mij twee dingen doen:solutionnl schreef op dinsdag 31 juli 2018 @ 10:32:
Ik heb nogmaals mijn de voorbeeld code doorgelopen, ik heb het nu grotendeels correct overgezet gekregen.
code:
1 Voor de 3e keer dezelfde enorme lap demo code
We do what we must because we can.
[ Voor 10% gewijzigd door Vos op 01-08-2018 09:30 ]
#36
Bedankt voor je reactie!Joepla schreef op zondag 29 juli 2018 @ 19:01:
@sloth ik heb mijn 1e SIM800 zodanig mishandeld, dat hij op een gegeven moment ook dit soort gedrag ging vertonen. In jouw geval zou ik in ieder geval de pincode even helemaal uitzetten (even in een gewone GSM doen en daar uitzetten), dan is dat in ieder geval geen probleem, ondanks dat je pincode geaccepteerd lijkt te worden.
Daarna zou ik de voeding verdenken... Heb je de mogelijkheid om een dikke elco (bv. 2200 uF, liefst low esr) dichtbij de voedingspinnen van de SIM800 te plaatsen? Een wat zwaardere voeding proberen zou ook handig zijn.
Verder kun je de module even terug naar fabrieksinstellingen zetten, AT cmd moet je even opzoeken.
En reset hem ook eens via de hardware reset input. Dat gaf bij mij ook vaak resultaat.
Ik weet nog steeds niet waardoor mijn SIM soms niet of pas na heel lange tijd zichzelf registreerde. Na een aansluitfout (te hoge kortstondige Vcc) deed hij dat helemaal nooit meer, leek erop dat alles nog werkte, behalve het zendgedeelte... Is het mogelijk dat er bij jou ook een hoge voedingsspanning op heeft gestaan?
Inmiddels heb ik een applicatie draaiend met zeer beperkte AT cmds, maar het werkt in ieder geval goed en stabiel. Zo af en toe krijg ik een status SMS en kan dan zien dat de SIM nog nooit langer dan 2 minuten offline is geweest, mogelijk zelfs nog nooit (draait nu een week of 3 continu).
Dat lijkt er wel op: Ik heb er zelf geen ervaring mee maar een snelle google levert bijvoorbeeld dit op.Vos schreef op woensdag 1 augustus 2018 @ 07:34:
Een noob vraag. Ik zou graag één (of twee) 4-axis joysticks willen gebruiken op mijn pc. Is dit mogelijk met Arduino?
Voorbeeld van joystick.
We do what we must because we can.
Bedankt, had wel gegoogled maar specifieker op dit type joystick. Ik zal er eens induiken.ResuCigam schreef op woensdag 1 augustus 2018 @ 08:58:
[...]
Dat lijkt er wel op: Ik heb er zelf geen ervaring mee maar een snelle google levert bijvoorbeeld dit op.
#36
[ Voor 3% gewijzigd door Joepla op 02-08-2018 13:39 ]
[ Voor 99% gewijzigd door Lennyz op 04-08-2018 11:43 ]
[ Voor 11% gewijzigd door SToRM666 op 05-08-2018 21:02 ]
PSN id: NL_SToRM
[ Voor 8% gewijzigd door warcow op 08-08-2018 13:45 ]
Cool! Heb je een library gebruikt om zo'n gauge te tekenen op dat scherm? Welke?warcow schreef op woensdag 8 augustus 2018 @ 13:45:
Net klaar met een 'fuel gauge' die bijhoudt hoe vol de accu van mijn bestuurbare auto nog is adhv voltage. Is een arduino pro mini met 0.96" oled schermpje. Komt in de FPV tonka die ik aan het bouwen ben.
[video]
Hieronder een voorbeeld waar ik ook naar heb gekeken:tsjoender schreef op woensdag 8 augustus 2018 @ 14:46:
[...]
Cool! Heb je een library gebruikt om zo'n gauge te tekenen op dat scherm? Welke?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
| #include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); const int numReadings = 25; int readings[numReadings]; // the readings from the analog input int readIndex = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average int xmax=128; int ymax=62; int xcenter=xmax/2; int ycenter=ymax/2+10; int arc=ymax/2; int angle=0; char* label[] = {"FUEL","COOLANT","INTAKE", "VOLT"}; int labelXpos[] = {53, 45, 49, 53}; #define potmeterPin A2 int p, w, m,a=10; u8g_uint_t xx=0; void gauge(uint8_t angle) { // draw border of the gauge if (w<0){ w=0; } u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT); // draw the needle float x1=sin(2*angle*2*3.14/360); float y1=cos(2*angle*2*3.14/360); u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT); u8g.setFont(u8g_font_chikita); // show scale labels u8g.drawStr( 20, 42, "0"); u8g.drawStr( 25, 18, "25"); u8g.drawStr( 60, 14, "50"); u8g.drawStr( 95, 18, "75"); u8g.drawStr( 105, 42, "100"); // show gauge label u8g.setPrintPos(labelXpos[0],32); u8g.print(label[0]); // show digital value and align its position u8g.setFont(u8g_font_profont22); u8g.setPrintPos(54,60); if (w<10){ u8g.print("0"); } if (w>99) { u8g.setPrintPos(47,60); } u8g.print(w); } void setup(void) { for (int thisReading = 0; thisReading < numReadings; thisReading++) { readings[thisReading] = 0; } u8g.setFont(u8g_font_chikita); u8g.setColorIndex(1); // assign default color value if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); } else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3); } else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1); } else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); } } void loop(void) { // subtract the last reading: total = total - readings[readIndex]; // read from the sensor: readings[readIndex] = analogRead(potmeterPin); // add the reading to the total: total = total + readings[readIndex]; // advance to the next position in the array: readIndex = readIndex + 1; // if we're at the end of the array... if (readIndex >= numReadings) { // ...wrap around to the beginning: readIndex = 0; } // calculate the average: average = total / numReadings; //p = analogRead(potmeterPin); p = average; w = map(p,472,604,0,100); //Change the first 2 numbers to calibrate voltage to 0-100% m = map(p,472,604,0,90); //Change the first 2 numbers to calibrate voltage to 0-100% // show needle and dial xx = m; if (xx<45){ xx=xx+135; } else if (xx>135){ xx=135; //below 0 should keep pointing at 180 degrees } else if (xx>90){ xx=45; //above 100 should keep pointing at 0 degrees } else { xx=xx-45; } // picture loop { u8g.firstPage(); do { gauge(xx); } while( u8g.nextPage() ); } } |
Voor een wekker met een ledstrip eraan vast. Qua dikte mogen de kabels hetzelfde zijn als degene die standaard in zo'n Arduino pakket zitten, dus dan kan ik de dunste wel nemen denk ik?Valen_76 schreef op dinsdag 7 augustus 2018 @ 12:35:
De een kan meer stroom doorvoeren dan de ander. De ander is weer flexibeler. Licht aan de gewenste toepassing. Let op de koper kern afmeting. 0,14mm^2 flexibele kern vs 0,5 mm^2 solide kern (lijkt het althans)
PSN id: NL_SToRM
Heb het nog niet onder vol zonlicht bekeken, doe ik binnenkort wel even. Ik verwacht dat het wel redelijk is want OLED.Joepla schreef op woensdag 8 augustus 2018 @ 18:59:
@warcow mooi gemaakt! Hoe is de afleesbaarheid van dit schermpje bij dag/zonlicht?
Ik zoek een scherm om een aantal zaken zichtbaar te maken op mijn motor (GPS snelheid, G-krachten, kompas, etc.) en zou dit het liefst ook grafisch willen. Ik kijk nu nog naar LCD schermpjes om de leesbaarheid overdag te garanderen.
[ Voor 16% gewijzigd door warcow op 09-08-2018 07:59 ]
Heel gaaf gemaaktwarcow schreef op woensdag 8 augustus 2018 @ 20:46:
[...]
Heb het nog niet onder vol zonlicht bekeken, doe ik binnenkort wel even. Ik verwacht dat het wel redelijk is want OLED.
Edit: In daglicht met veel zon is het heel goed te doen maar die van mij heeft wat een matte laag, als ik hem zo hou dat de zon mijn ogen in reflecteert dan is het scherm helemaal opgelicht en niet meer afleesbaar.
[ Voor 68% gewijzigd door Atmoz op 09-08-2018 18:59 ]
Ok thx. Reflectie is gewoon moeilijk, daar zijn weinig schermen tegen opgewassen. Zal toch eens kijken of ik er ook wat mee kan. De OLED schermpjes zijn alleen extreem klein, heb er nog 1 liggen van 1", maar nog nooit gebruikt.warcow schreef op woensdag 8 augustus 2018 @ 20:46:
[...]
Edit: In daglicht met veel zon is het heel goed te doen maar die van mij heeft wat een matte laag, als ik hem zo hou dat de zon mijn ogen in reflecteert dan is het scherm helemaal opgelicht en niet meer afleesbaar.
Er zijn ook wat grotere schermen goed verkrijgbaar. Heb zelfs wel wat e-ink schermen gezien, misschien is dat ideaal voor buiten afleesbaar.. (ook goed zuinig)Joepla schreef op donderdag 9 augustus 2018 @ 10:00:
[...]
Ok thx. Reflectie is gewoon moeilijk, daar zijn weinig schermen tegen opgewassen. Zal toch eens kijken of ik er ook wat mee kan. De OLED schermpjes zijn alleen extreem klein, heb er nog 1 liggen van 1", maar nog nooit gebruikt.
1.3" OLED:Joepla schreef op donderdag 9 augustus 2018 @ 14:17:
@warcow Ik kom ze zelden tegen, vaak zijn het dan TFT LCD's. Maar wie weet vind ik er een.
E-ink is denk ik wel een leuk alternatief, maar meestal erg slecht qua screen refresh (logisch) en op de motor wil ik graag direct resultaat, ipv. vertraagde of beperkte schermopbouw. Energieverbruik is uiteraard ook geen probleem.
[ Voor 12% gewijzigd door warcow op 09-08-2018 14:41 ]
Ligt er aan hoeveel stroom er door die ledstrip heen gaat.De ledstrip zal je waarschijnlijk moeten voeden met dikkere kabels. Voor de aansturing via de innetjes van de arduino (die niet zoveel stroom leveren) zal de dunste prima zijn. Is de ledstrip met digitale aansturing of zijn het domme (RGB) leds met gedeelde anode/kathode?SToRM666 schreef op woensdag 8 augustus 2018 @ 20:04:
[...]
Voor een wekker met een ledstrip eraan vast. Qua dikte mogen de kabels hetzelfde zijn als degene die standaard in zo'n Arduino pakket zitten, dus dan kan ik de dunste wel nemen denk ik?
Ik heb inmiddels bovenstaande meer dan een week 'in productie' en het werkt tot nu toe feilloossloth schreef op zaterdag 4 augustus 2018 @ 09:13:
Ik heb inmiddels op jullie advies getest met een elco, helaas met hetzelfde resultaat als voorheen. Ook de pincode uitzetten en factory instellingen helpen niet.
Zoals jullie misschien al merken is Arduino, en elektronica in het algemeen, nieuw voor me. Klopt het volgend schema van mijn proefopstelling? Bedoelen jullie dit met de elco zo zicht mogelijk bij de gsm module plaatsen?
https://i.imgur.com/5p8poxd.png
De blauwe kabel komt samen in een Wago steekklem die GND van Arduino, de - van het breadboard en de GND van de SIM800l module met elkaar verbinden.
Pin layout is verder (vanaf SIM800l bekeken)
GND > GND
VCC > breadboard net naast de + pool van de elco
TX > TX Arduino (pin 7)
RX > RX Arduino (pin 8
Als stroomvoorziening gebruik ik eerst een 7.5V 1,5A voeding die vervolgens door een LM2596 op 4,1V wordt gelimiteerd.
[ Voor 5% gewijzigd door sloth op 30-08-2018 18:15 ]
[ Voor 4% gewijzigd door SToRM666 op 06-10-2018 19:00 ]
PSN id: NL_SToRM
[ Voor 7% gewijzigd door SToRM666 op 16-10-2018 18:53 ]
PSN id: NL_SToRM
404 Signature not found
PSN id: NL_SToRM
Eigenlijk onmisbaar voor sommige zaken. Soms gaat de spanning eraf zonder dat je dat wilt (netspanningsuitval, komt weinig voor, maar toch...). En best makkelijk te maken.SToRM666 schreef op dinsdag 16 oktober 2018 @ 18:53:
Schrijven naar EEPROM zou ik ook nog wel handig vinden, aangezien ik nu telkens alles opnieuw moet instellen van zodra de spanning eraf gaat.
[ Voor 15% gewijzigd door Joepla op 16-10-2018 22:13 ]
[ Voor 23% gewijzigd door SToRM666 op 16-10-2018 22:40 ]
PSN id: NL_SToRM
PSN id: NL_SToRM
[ Voor 28% gewijzigd door Atmoz op 29-10-2018 08:34 ]
Die Chinese shields hoeven echt niet zo slecht te zijn hoorAtmoz schreef op maandag 29 oktober 2018 @ 08:26:
Het ziet er naar uit dat de ethernet-module die ik altijd graag gebruikte (met W5500 chip) en gewoon direct passend op een Arduino Uno of MEGA niet meer wordt gemaakt
Ik vraag mij af: weten jullie nog ergens een winkel welke deze (de originele van Arduino) nog verkoopt? Graag zou ik er nog wat inslaan voordat ze dadelijk helemaal nergens meer te krijgen zijn.
[edit]
En verder vraag ik me af hoe jullie dat (in de toekomst) gaan doen? Stel je hebt een Arduino MEGA2560, en je wilt hier ethernet op maken, welke ethernet-module moet je dan nemen? Ze worden niet meer geproduceerd, dus ben je dan verplicht om die nep prullen uit China te nemen?
Wat Arduino-spulletjes betreft, heb ik alleen maar CN versies. Al een aantal leuke projectjes mee gebouwd, zelfs professionele toepassingen. Zelden zoveel pret gehad voor zo weinig kosten.Atmoz schreef op maandag 29 oktober 2018 @ 08:26:
...Ze worden niet meer geproduceerd, dus ben je dan verplicht om die nep prullen uit China te nemen?
Hmzzz, daar heb ik nog maar weinig mee gespeeld eigenlijk.mcDavid schreef op maandag 29 oktober 2018 @ 09:31:
Da's toch dat ding wat duurder is dan een Raspberry Pi? Ik zou in zo'n geval dan een Raspberry Pi gebruiken.
Het hoeft natuurlijk niet nee, maar het komt toch zéér geregeld voor. Ik heb in het verleden heel wat stapels Arduino's, shields, sensoren en weet ik wat allemaal laten komen uit China, maar uiteindelijk was ik er helemaal klaar mee. Veel (gedeeltelijk) defecte Arduino boards, shields die al bij aankomt DOA waren en weer andere shields die er binnen enkele maanden al mee ophielden. Doorgefikte componenten. En dan heb ik het hele verhaal over alternatieve/niet goed werkende drivers nog niet genoemd. Uiteindelijk zorgt dat er allemaal voor dat je de zin ervan over gaat. Hoeveel uren (dagen...weken!) ik vroeger in m'n studententijd niet ben "kwijtgeraakt" aan klooien met drivers of uiteindelijk toch een kapot board....tsjoender schreef op maandag 29 oktober 2018 @ 09:39:
Die Chinese shields hoeven echt niet zo slecht te zijn hoor.
Thanks!Maar Adafruit heeft kwaliteitsproducten en een Ethernet shield:
https://www.adafruit.com/product/2971
Als het allemaal werkt is het inderdaad fantastisch dat je met zulke goedkope dingen zo'n sjieke projecten kunt maken. Daar ben ik het volledig mee eens.Joepla schreef op maandag 29 oktober 2018 @ 19:05:
Wat Arduino-spulletjes betreft, heb ik alleen maar CN versies. Al een aantal leuke projectjes mee gebouwd, zelfs professionele toepassingen. Zelden zoveel pret gehad voor zo weinig kosten.
Kun je misschien aangeven waarom het "prullen" zijn?
Sja ligt eraan wat je wilt doen natuurlijk. Maar als je een toepassing met ethernet hebt, is een RPi al snel een heel stuk praktischer dan een Arduino.Atmoz schreef op maandag 29 oktober 2018 @ 21:36:
[...]
Hmzzz, daar heb ik nog maar weinig mee gespeeld eigenlijk.
Ik dacht eigenlijk dat ze sowieso (veel) duurder waren, en ook té krachtig voor de toepassingen die ik voor ogen heb. Maar het kan natuurlijk nooit kwaad om er eens naar te kijken
Ik koop ook alles zo goedkoop mogelijk uit china, maar ik kan wel wat dingen noemen hoor:Joepla schreef op maandag 29 oktober 2018 @ 19:05:
[...]
Wat Arduino-spulletjes betreft, heb ik alleen maar CN versies. Al een aantal leuke projectjes mee gebouwd, zelfs professionele toepassingen. Zelden zoveel pret gehad voor zo weinig kosten.
Kun je misschien aangeven waarom het "prullen" zijn?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| #define button 3 #define lbell 4 #define rbell 5 #define edail 7 #define pdail 8 // variables will change: int buttonState = 0; // variable for reading the pushbutton status void setup() { Serial.begin(9600); pinMode(lbell, OUTPUT); pinMode(rbell, OUTPUT); pinMode(button, INPUT); } void loop() { // read the state of the pushbutton value: buttonState = digitalRead(button); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn LED on: Serial.println("doorbell button is pressed"); digitalWrite(lbell, HIGH); delay(10); digitalWrite(lbell, LOW); delay(10); digitalWrite(rbell, HIGH); delay(10); digitalWrite(rbell, LOW); delay(10); } else { } } |
Voor MySensors kun je wait gebruiken:SuperKris schreef op woensdag 31 oktober 2018 @ 01:14:
Vraagje voor de experts....
Ik wil een signaal genereren over 2 GPIO's een voorbeeld van mijn testje:
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #define button 3 #define lbell 4 #define rbell 5 #define edail 7 #define pdail 8 // variables will change: int buttonState = 0; // variable for reading the pushbutton status void setup() { Serial.begin(9600); pinMode(lbell, OUTPUT); pinMode(rbell, OUTPUT); pinMode(button, INPUT); } void loop() { // read the state of the pushbutton value: buttonState = digitalRead(button); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn LED on: Serial.println("doorbell button is pressed"); digitalWrite(lbell, HIGH); delay(10); digitalWrite(lbell, LOW); delay(10); digitalWrite(rbell, HIGH); delay(10); digitalWrite(rbell, LOW); delay(10); } else { } }
het laatst stukje moet ca. 25 keer herhaald worden. Daarna ca. 2 tot 3 seconden niets doen
En dit moet dan weer een keer of 3-4 herhaald worden. Een beetje zoals een telefoon zeg maar. (dat is het ook namelijk)
Beide pinnen mogen nooit gelijk hoog zijn. Bovenstaand voorbeeld heeft 10ms als tijd dat een pin hoog is. Dit staat nog niet helemaal vast Dit kan nog tussen de ca. 5 en 20ms varieren.
Tijdens het genereren van het signaal moet de arduino gewoon doorlopen en beschikbaar zijn voor signalen vanaf de radio (mysensors)
Hoe kan ik dit het beste oppakken? Uiteraard niet met delay, maar hoe dan wel?
Joepla schreef op dinsdag 16 oktober 2018 @ 22:10:
[...]
Eigenlijk onmisbaar voor sommige zaken. Soms gaat de spanning eraf zonder dat je dat wilt (netspanningsuitval, komt weinig voor, maar toch...). En best makkelijk te maken.
Cool project trouwens! Ik denk erover om een Nixie-klok te gaan bouwen, op basis van de GPS tijd.
[Afbeelding]
Xiaomi 13T Pro
Oh wow... sinds wanneer zit die er in? Ik heb in het verleden al meerdere keren om delay heen lopen werken met millis en timer libraries enzo.tsjoender schreef op woensdag 31 oktober 2018 @ 11:12:
[...]
Voor MySensors kun je wait gebruiken:
https://www.mysensors.org/download/sensor_api_20
(even doorscrollen naar beneden naar "Waiting")
Thanks, ik ben in principe bekend met millis, maar weet ook weer niet of dit de meest ideale manier is.
Die wait is beschikbaar wanneer je de MySensors library include in je code. Dan kan je die aanroepen voor alles waar je een timeout in wilt bouwen.SuperKris schreef op woensdag 31 oktober 2018 @ 15:59:
[...]
Oh wow... sinds wanneer zit die er in? Ik heb in het verleden al meerdere keren om delay heen lopen werken met millis en timer libraries enzo.
Weet jij toevallig ook of deze functie alleen voor mysensors en de radio werkt, of ook voor alle andere code en dus ook het uitlezen van pinnen.
[...]
Thanks, ik ben in principe bekend met millis, maar weet ook weer niet of dit de meest ideale manier is.
Ik ben vooral op zoek naar een methode om dit makkelijk dit signaal te creëren:
[Afbeelding]
Tijd A is ca. 5 tot 25 ms. (nader te bepalen)
Tijd B is ca. 5 tot 25 ms. (nader te bepalen)
Tijd C is ca. 1000 tot 3000 ms. (nader te bepalen)
Periode 1 moet ca 10 tot 50 keer herhaald worden (nader te bepalen). Daarna wachten voor tijd C.
Daarna moet bovenstaand weer 2 tot 4 keer (nader te bepalen) herhaald worden.
Als ik even van het germiddelde uit ga zijn dat 4x25x4= 400 regels code. Dat is heel veel copy paste
Dat moet slimmer kunnen toch?
Geen idee. Het was gewoon een voorbeeld van een Nixieklokje. Ik wil alles zelf ontwerpen, programmeren en bouwen. Bouwpakketten zijn wel makkelijk, maar daar is voor mij wat te weinig uitdaging in.
Dat is wel het gaafst idd. Ik heb ook zelf alles ontworpen en geprogrammeerd.Joepla schreef op donderdag 1 november 2018 @ 12:17:
[...]
Geen idee. Het was gewoon een voorbeeld van een Nixieklokje. Ik wil alles zelf ontwerpen, programmeren en bouwen. Bouwpakketten zijn wel makkelijk, maar daar is voor mij wat te weinig uitdaging in.
Heb onlangs 6 stuks IN-8 buizen (new old stock) besteld in Rusland, buisvoeten, hoogspanningsvoedingtje, drivers, logica, etc. Nu nog tijd vinden, wordt een redelijk gepuzzel met schuifregisters e.d.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| /*************************************************** This is an example for the HTU21D-F Humidity & Temp Sensor Designed specifically to work with the HTU21D-F sensor from Adafruit ----> https://www.adafruit.com/products/1899 These displays use I2C to communicate, 2 pins are required to interface ****************************************************/ #include <Wire.h> #include "Adafruit_HTU21DF.h" // Connect Vin to 3-5VDC // Connect GND to ground // Connect SCL to I2C clock pin (A5 on UNO) // Connect SDA to I2C data pin (A4 on UNO) Adafruit_HTU21DF htu = Adafruit_HTU21DF(); void setup() { Serial.begin(9600); Serial.println("HTU21D-F test"); if (!htu.begin()) { Serial.println("Couldn't find sensor!"); while (1); } } void loop() { float temp = htu.readTemperature(); float rel_hum = htu.readHumidity(); Serial.print("Temp: "); Serial.print(temp); Serial.print(" C"); Serial.print("\t\t"); Serial.print("Humidity: "); Serial.print(rel_hum); Serial.println(" \%"); delay(500); } |
Uiteraard!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
| /// ##### mysensors setup ###### #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define CHILD_ID 8 // child ID numer for mysensors network // ###### Include libaries ##### #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> // ###### I/O pin number setup ###### #define button 3 // input pin activated when doorbell button is pressed #define edail 8 // input pin activated when dail is used (Enable Dail) #define pdail 7 // input pin activated with each tick of the dail (Pulse Dial) #define lbell 4 // output pin to swing bellh hamer left #define rbell 5 // output Pin to swing bellh hamer right // ##### Debouncer variables ##### Bounce debouncerButton = Bounce(); // Create button debouncer for doorbell button Bounce debouncerEdail = Bounce(); // Create button debouncer for Enable Dail Bounce debouncerPdail = Bounce(); // Create button debouncer for Pulse Dial int valueButton = 0; int oldValueButton = 0; int valueEdail = 0; int oldValueEdail = 0; int valuePdail = 0; int oldValuePdail = 0; int dailCount = 0; MyMessage msg(CHILD_ID,V_TRIPPED); void setup() { //##### I/O pin function setup ##### pinMode(button,INPUT); pinMode(edail, INPUT); pinMode(pdail, INPUT); pinMode(lbell, OUTPUT); pinMode(rbell, OUTPUT); // ##### Debouncer setup ##### debouncerButton.attach(button); debouncerButton.interval(5); debouncerEdail.attach(edail); debouncerEdail.interval(5); debouncerPdail.attach(pdail); debouncerPdail.interval(10); } void presentation() { // Register binary input sensor to gw (they will be created as child devices) // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. present(CHILD_ID, S_DOOR); } // Check if digital input has changed and send in new value void loop() { debouncerButton.update(); // Update debouncer for doorbell button int valueButton = debouncerButton.read(); // Set current value of doorbell button debouncerEdail.update(); // Update debouncer for enable dail int valueEdail = debouncerEdail.read(); // Set current value of enable dail debouncerPdail.update(); // Update debouncer for pulse dail int valuePdail = debouncerPdail.read(); // Set current value of pulse dail // ##### Mysensors code to sent message ##### if (valueButton != oldValueButton) { // Check if the value of the button has changed send(msg.set(valueButton==HIGH ? 1 : 0)); // Transmit the new value oldValueButton = valueButton; // Change old value so this doenst loop } // ###### Code for checking enable dail and sending state trough serial ###### if (valueEdail != oldValueEdail && valueEdail == HIGH) { // Check if dail enable has changed AND if currently its currently activated Serial.println("dail is activated..."); // Sent message oldValueEdail = valueEdail;} // Change old value so this doenst loop else if (valueEdail != oldValueEdail && valueEdail == LOW) { // Check if dail enable has changed AND if currently its currently deactivated Serial.println("dail is deactivated..."); // Sent message oldValueEdail = valueEdail; // Change old value so this doenst loop dailCount = -1; } // ###### Code for checking pusle dail and sending state trough serial ###### if (valuePdail != oldValuePdail && valueEdail == HIGH) { // if (valuePdail = LOW) { dailCount++; Serial.print("Tick! Total ammout of pulses: "); Serial.println (dailCount); oldValuePdail = valuePdail; // Change old value so this doenst loop // } } // Serial.println(valuePdail); } |
Bij de laatste if heb je een gelijkteken te weinig. Dus == ipv = (been there done thatSuperKris schreef op zondag 4 november 2018 @ 17:49:
Nog een vraagje, ik ben onderstaande code aan het maken en er is 1 ding waar ik niet uit kom.
In het laatste stukje (Code for checking pusle dail and sending state trough serial) leest de code de status van een pin uit. Deze is constant hoog, en schakelt een x aantal keer naar 0. Momenteel telt en serial print hij elke verandering dus van hoog naar laag, en van laag naar hoog.
Als de pin dus 3 keer naar beneden getrokken wordt, zijn dat 6 veranderingen, en de teller staat dan op 6. Dit moet natuurlijk 3 zijn.
Ik wil dus de voorwaarde toevoegen dat hij alleen mag tellen een serial print mag doen als de waarde van hoog naar laag gaat. Wanneer ik dit probeer registered hij geen enkele puls meer.
Hoe los ik dit op?
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 /// ##### mysensors setup ###### #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define CHILD_ID 8 // child ID numer for mysensors network // ###### Include libaries ##### #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> // ###### I/O pin number setup ###### #define button 3 // input pin activated when doorbell button is pressed #define edail 8 // input pin activated when dail is used (Enable Dail) #define pdail 7 // input pin activated with each tick of the dail (Pulse Dial) #define lbell 4 // output pin to swing bellh hamer left #define rbell 5 // output Pin to swing bellh hamer right // ##### Debouncer variables ##### Bounce debouncerButton = Bounce(); // Create button debouncer for doorbell button Bounce debouncerEdail = Bounce(); // Create button debouncer for Enable Dail Bounce debouncerPdail = Bounce(); // Create button debouncer for Pulse Dial int valueButton = 0; int oldValueButton = 0; int valueEdail = 0; int oldValueEdail = 0; int valuePdail = 0; int oldValuePdail = 0; int dailCount = 0; MyMessage msg(CHILD_ID,V_TRIPPED); void setup() { //##### I/O pin function setup ##### pinMode(button,INPUT); pinMode(edail, INPUT); pinMode(pdail, INPUT); pinMode(lbell, OUTPUT); pinMode(rbell, OUTPUT); // ##### Debouncer setup ##### debouncerButton.attach(button); debouncerButton.interval(5); debouncerEdail.attach(edail); debouncerEdail.interval(5); debouncerPdail.attach(pdail); debouncerPdail.interval(10); } void presentation() { // Register binary input sensor to gw (they will be created as child devices) // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. present(CHILD_ID, S_DOOR); } // Check if digital input has changed and send in new value void loop() { debouncerButton.update(); // Update debouncer for doorbell button int valueButton = debouncerButton.read(); // Set current value of doorbell button debouncerEdail.update(); // Update debouncer for enable dail int valueEdail = debouncerEdail.read(); // Set current value of enable dail debouncerPdail.update(); // Update debouncer for pulse dail int valuePdail = debouncerPdail.read(); // Set current value of pulse dail // ##### Mysensors code to sent message ##### if (valueButton != oldValueButton) { // Check if the value of the button has changed send(msg.set(valueButton==HIGH ? 1 : 0)); // Transmit the new value oldValueButton = valueButton; // Change old value so this doenst loop } // ###### Code for checking enable dail and sending state trough serial ###### if (valueEdail != oldValueEdail && valueEdail == HIGH) { // Check if dail enable has changed AND if currently its currently activated Serial.println("dail is activated..."); // Sent message oldValueEdail = valueEdail;} // Change old value so this doenst loop else if (valueEdail != oldValueEdail && valueEdail == LOW) { // Check if dail enable has changed AND if currently its currently deactivated Serial.println("dail is deactivated..."); // Sent message oldValueEdail = valueEdail; // Change old value so this doenst loop dailCount = -1; } // ###### Code for checking pusle dail and sending state trough serial ###### if (valuePdail != oldValuePdail && valueEdail == HIGH) { // if (valuePdail = LOW) { dailCount++; Serial.print("Tick! Total ammout of pulses: "); Serial.println (dailCount); oldValuePdail = valuePdail; // Change old value so this doenst loop // } } // Serial.println(valuePdail); }
Thanks, maar die had ik zelf ook al gevonden! Slordig van mij om de code foutief door te zetten, maar dat is het dus niet.tsjoender schreef op zondag 4 november 2018 @ 19:21:
[...]
Bij de laatste if heb je een gelijkteken te weinig. Dus == ipv = (been there done that)
Hmmm, je hebt eerst de voorwaarde dat die waarde hoog moet zijn (en ongelijk aan de vorige waarde) en dan volgt de voorwaarde dat die laag moet zijn. Het zal nooit beide zijn, dus dat blok wordt dan niet uitgevoerd. Waarschijnlijk moet je alleen checken dat die ongelijk is en laag.SuperKris schreef op zondag 4 november 2018 @ 19:22:
[...]
Thanks, maar die had ik zelf ook al gevonden! Slordig van mij om de code foutief door te zetten, maar dat is het dus niet.
1
2
3
4
5
6
7
8
9
| // ###### Code for checking pusle dail and sending state trough serial ###### if (valuePdail != oldValuePdail && valueEdail == HIGH) { if (valuePdail == LOW) { dailCount++; Serial.print("Tick! Total ammout of pulses: "); Serial.println (dailCount); } oldValuePdail = valuePdail; // Change old value so this doenst loop } |
[ Voor 22% gewijzigd door Joepla op 05-11-2018 21:26 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
| /// ##### mysensors setup ###### #define ProjectName "OldPhone" // Name that is vissible in controller #define ProjectVersion "0,1" // Version that is vissible in controller #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define childIdDoor 1 // child ID number used by mysensors foor doorbell button #define chuildIdDail_1 101 // child ID number used by mysensors when the number 1 is dailed #define chuildIdDail_2 102 // child ID number used by mysensors when the number 2 is dailed #define chuildIdDail_3 103 // child ID number used by mysensors when the number 3 is dailed #define chuildIdDail_4 104 // child ID number used by mysensors when the number 4 is dailed #define chuildIdDail_5 105 // child ID number used by mysensors when the number 5 is dailed #define chuildIdDail_6 106 // child ID number used by mysensors when the number 6 is dailed #define chuildIdDail_7 107 // child ID number used by mysensors when the number 7 is dailed #define chuildIdDail_8 108 // child ID number used by mysensors when the number 8 is dailed #define chuildIdDail_9 109 // child ID number used by mysensors when the number 9 is dailed #define chuildIdDail_10 110 // child ID number used by mysensors when the number 0 is dailed // ###### Include libraries ##### #include <SPI.h> // needed for NRF24 #include <MySensors.h> // mysensors library #include <Bounce2.h> // for debouncing buttons and dail // ###### I/O pin number setup ###### #define button 3 // input pin activated when doorbell button is pressed #define edail 8 // input pin activated when dail is used (Enable Dail) #define pdail 7 // input pin activated with each tick of the dail (Pulse Dial) #define lbell 4 // output pin to swing bellh hamer left #define rbell 5 // output Pin to swing bellh hamer right // ##### Debouncer variables ##### Bounce debouncerButton = Bounce(); // Create button debouncer for doorbell button Bounce debouncerEdail = Bounce(); // Create button debouncer for Enable Dail Bounce debouncerPdail = Bounce(); // Create button debouncer for Pulse Dial int valueButton = 0; // Value int oldValueButton = 0; int valueEdail = 0; int oldValueEdail = 0; int valuePdail = 0; int oldValuePdail = 0; int dailCount = 0; int newDailCount = 0; int ring = 0; int ringX = 15; int onPulse = 20; int offPulse = 10; int repeat = 0; int repeatX = 4; int ringPause = 2000; // ##### setup MySensors message containers ##### MyMessage msgDoor(childIdDoor,V_STATUS); // message container used for doorbell button MyMessage msgDail_1(chuildIdDail_1,V_STATUS); // message container used when the number 1 is dailed MyMessage msgDail_2(chuildIdDail_2,V_STATUS); // message container used when the number 2 is dailed MyMessage msgDail_3(chuildIdDail_3,V_STATUS); // message container used when the number 3 is dailed MyMessage msgDail_4(chuildIdDail_4,V_STATUS); // message container used when the number 4 is dailed MyMessage msgDail_5(chuildIdDail_5,V_STATUS); // message container used when the number 5 is dailed MyMessage msgDail_6(chuildIdDail_6,V_STATUS); // message container used when the number 6 is dailed MyMessage msgDail_7(chuildIdDail_7,V_STATUS); // message container used when the number 7 is dailed MyMessage msgDail_8(chuildIdDail_8,V_STATUS); // message container used when the number 8 is dailed MyMessage msgDail_9(chuildIdDail_9,V_STATUS); // message container used when the number 9 is dailed MyMessage msgDail_10(chuildIdDail_10,V_STATUS); // message container used when the number 0 is dailed void setup() { //##### I/O pin function setup ##### pinMode(button,INPUT); //set the already defined I/O pin as input pinMode(edail, INPUT); //set the already defined I/O pin as input pinMode(pdail, INPUT); //set the already defined I/O pin as input pinMode(lbell, OUTPUT); //set the already defined I/O pin as output pinMode(rbell, OUTPUT); //set the already defined I/O pin as output // ##### Debouncer setup ##### debouncerButton.attach(button); debouncerButton.interval(5); debouncerEdail.attach(edail); debouncerEdail.interval(5); debouncerPdail.attach(pdail); debouncerPdail.interval(5); } // ##### Function of MySensors that presents all attached sensors to the controller ##### void presentation() { sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller present(childIdDoor, S_BINARY); // Present doorbell button as binary switch present(chuildIdDail_1, S_BINARY); // Present the dailing of number 1 as binary switch present(chuildIdDail_2, S_BINARY); // Present the dailing of number 2 as binary switch present(chuildIdDail_3, S_BINARY); // Present the dailing of number 3 as binary switch present(chuildIdDail_4, S_BINARY); // Present the dailing of number 4 as binary switch present(chuildIdDail_5, S_BINARY); // Present the dailing of number 5 as binary switch present(chuildIdDail_6, S_BINARY); // Present the dailing of number 6 as binary switch present(chuildIdDail_7, S_BINARY); // Present the dailing of number 7 as binary switch present(chuildIdDail_8, S_BINARY); // Present the dailing of number 8 as binary switch present(chuildIdDail_9, S_BINARY); // Present the dailing of number 9 as binary switch present(chuildIdDail_10, S_BINARY); // Present the dailing of number 0 as binary switch } void loop() { // ##### debouncer updater ##### debouncerButton.update(); // Update debouncer for doorbell button valueButton = debouncerButton.read(); // Set current value of doorbell button debouncerEdail.update(); // Update debouncer for enable dail valueEdail = debouncerEdail.read(); // Set current value of enable dail debouncerPdail.update(); // Update debouncer for pulse dail valuePdail = debouncerPdail.read(); // Set current value of pulse dail // ##### Mysensors code to check doorbell button and sent message ##### if (valueButton != oldValueButton) { // Check if the value of the button has changed send(msgDoor.set(valueButton==HIGH ? 1 : 0)); // Transmit the new value oldValueButton = valueButton; // Change old value so this doenst loop } // ##### Mysensors code to read dail counter and sent message as one individual sensor ##### switch (newDailCount) { // Check the current vallue of the completed counter case 1: // if value is equal to 1 send(msgDail_1.set(1)); // Transmit ON message for dail switch 1 send(msgDail_1.set(0)); // Transmit OFF message for dail switch 1. Some home automation software prefers this. break; // end of case case 2: // if value is equal to 2 send(msgDail_2.set(1)); // Transmit ON message for dail switch 2 send(msgDail_2.set(0)); // Transmit OFF message for dail switch 2. Some home automation software prefers this. break; // end of case case 3: // if value is equal to 3 send(msgDail_3.set(1)); // Transmit ON message for dail switch 3 send(msgDail_3.set(0)); // Transmit OFF message for dail switch 3. Some home automation software prefers this. break; // end of case case 4: // if value is equal to 4 send(msgDail_4.set(1)); // Transmit ON message for dail switch 4 send(msgDail_4.set(0)); // Transmit OFF message for dail switch 4. Some home automation software prefers this. break; // end of case case 5: // if value is equal to 5 send(msgDail_5.set(1)); // Transmit ON message for dail switch 5 send(msgDail_5.set(0)); // Transmit OFF message for dail switch 5. Some home automation software prefers this. break; // end of case case 6: // if value is equal to 6 send(msgDail_6.set(1)); // Transmit ON message for dail switch 6 send(msgDail_6.set(0)); // Transmit OFF message for dail switch 6. Some home automation software prefers this. break; // end of case case 7: // if value is equal to 7 send(msgDail_7.set(1)); // Transmit ON message for dail switch 7 send(msgDail_7.set(0)); // Transmit OFF message for dail switch 7. Some home automation software prefers this. break; // end of case case 8: // if value is equal to 8 send(msgDail_8.set(1)); // Transmit ON message for dail switch 8 send(msgDail_8.set(0)); // Transmit OFF message for dail switch 8. Some home automation software prefers this. break; // end of case case 9: // if value is equal to 9 send(msgDail_9.set(1)); // Transmit ON message for dail switch 9 send(msgDail_9.set(0)); // Transmit OFF message for dail switch 9. Some home automation software prefers this. break; // end of case case 10: // if value is equal to 10 send(msgDail_10.set(1)); // Transmit ON message for dail switch 10 send(msgDail_10.set(0)); // Transmit OFF message for dail switch 10. Some home automation software prefers this. break; // end of case } newDailCount = 0; // Reset the completed counter so this doesnt loop // ###### Code for checking enable dail and sending state trough serial ###### if (valueEdail != oldValueEdail && valueEdail == HIGH) { // Check if enable dail has changed AND if its currently its currently activated Serial.println("dail is activated..."); // If so sent message oldValueEdail = valueEdail;} // And change old value so this doenst loop else if (valueEdail != oldValueEdail && valueEdail == LOW) { // Check if enable dail has changed AND if its currently its currently deactivated Serial.println("dail is deactivated..."); // If so sent message newDailCount = dailCount; // Write the counted pulses to the New Dail Count dailCount = 0; // Reset the dail count for next dail oldValueEdail = valueEdail; // And change old value so this doenst loop } // ###### Code for checking pusle dail and sending state trough serial ###### if (valuePdail != oldValuePdail && valueEdail == HIGH) { // Check if dail pulse has changed AND if currently its currently activated if (valuePdail == LOW) { // Only take action when the signal goes from high to low to prevent double count dailCount++; // If the conditions are met increase counter by 1 Serial.print("Tick! Total ammout of pulses: "); // Serial print a messagge saying a pulse was detected Serial.println (dailCount); // Serial print a the current value of the counter } oldValuePdail = valuePdail; // Change old value so this doenst loop } if (valueButton == HIGH) { // If the boorbell button was pressed (read from debouncer) while (repeat < repeatX){ // start a loop if the number of repeats isnt reached yet (a repeat is the time a bell is ringed pauesed) repeat++; // add 1 count to the "repeat" counter while (ring < ringX){ // start a loop if the number of rings isnt reached yet (a ring is the hammer hitting each bell once) ring++; // add 1 count to the "ring" counter digitalWrite(lbell, HIGH); // power the bell coil so that the hammer hits the left bell !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(onPulse); // hold for the amount of ms set for "onPulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! digitalWrite(lbell, LOW); // power down the bell coil !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(offPulse); // wait for the amount of ms set for "offpulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! digitalWrite(rbell, HIGH); // power the bell coil so that the hammer hits the right bell !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(onPulse); // hold for the amount of ms set for "onPulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! digitalWrite(rbell, LOW); // power down the bell coil !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(offPulse); // wait for the amount of ms set for "offpulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! } // go back to start if loop till "ring" has the same value as "ringX" wait (ringPause); // wait for the amount of ms set for "ringPause" if (ring == ringX){ // if the amount of "ring" is the same as the amount set in "ringX".... ring = 0; // reset the "ring" counter } } } if (repeat == repeatX){ // if the amount of "repeat" is the same as the amount set in "repeatX".... repeat = 0; // reset the "repeat" counter } } |
Hmm, also ik iets met weergave doe, pak ik net zo graag een Raspberry Pi. Of je praat via USB met een applicatie op PC.Joepla schreef op maandag 5 november 2018 @ 21:19:
Niemand hier die wat met Nextion schermpjes doet? Lijkt me erg makkelijk om daar in no-time iets moois mee te maken!
Zit op een 3.5" Enhanced versie te wachten...
Ga jij dan maar eens een trend weergeven op je ledjes. Of een analoge meter.Accretion schreef op maandag 5 november 2018 @ 22:14:
[...]
Hmm, also ik iets met weergave doe, pak ik net zo graag een Raspberry Pi. Of je praat via USB met een applicatie op PC.
Wat is er mis met ledjes en knopjes?
Mijn punt is dat je de apparatuur moet gebruiken die geschikt is voor de functie.Joepla schreef op maandag 5 november 2018 @ 23:13:
[...]
Ga jij dan maar eens een trend weergeven op je ledjes. Of een analoge meter.
Een Rpi vergelijken met een Arduino vind ik al wat bijzonder, maar ledjes/knopjes vergelijken met een aardig geavanceerd touch-schermpje nog meer...
Laten we het erop houden dat ik applicaties in gedachten heb, waarbij het erg onpraktisch is om een PC met scherm mee te zeulen en het toepassen van wat ledjes en knopjes niet in in de buurt komt van wat een 24 euro schermpje te bieden heeft.
Ik heb een nextion schermpje gebruikt voor het bedienen van een alarmsysteem met arduino.Joepla schreef op maandag 5 november 2018 @ 21:19:
Niemand hier die wat met Nextion schermpjes doet? Lijkt me erg makkelijk om daar in no-time iets moois mee te maken!
Zit op een 3.5" Enhanced versie te wachten...
Apple iPhone 16e LG OLED evo G5 Google Pixel 10 Samsung Galaxy S25 Star Wars: Outlaws Nintendo Switch 2 Apple AirPods Pro (2e generatie) Sony PlayStation 5 Pro
Tweakers is onderdeel van
DPG Media B.V.
Alle rechten voorbehouden - Auteursrecht © 1998 - 2025
•
Hosting door TrueFullstaq