Странные глюки с энкодером в моём коде + странности с nRF24L01+
- Войдите на сайт для отправки комментариев
Чт, 16/05/2019 - 21:10
Использую библиотеку (GyverEncoder 3.1) в своём проекте, в примерах библиотеки мой самодельный энкодер (сам энкодер взят со старой автомагнитолы и к нему была сделана плата с подтягивающими резисторами) работает нормально, но вот в коде проекта энкодер срабатывает поворота наверно со 100500-го. Не могу понять в чём проблема.
И нашел ещё проблему, при передачи в запись массива transmit_data[6] (TX_response.ino) данных (значение 100), на приёмнике (RX_response.ino) в той же записи массива received_data[6] творится какая-то дичь, значения скачут от 10 до 7000+, значения остальных принимаемых данных массива в норме. При обратной передаче тоже какая-то дичь, значение Bat (transmit_data[1] в RX_response.ino) нормальное (к примеру 89), но на передатчик (recieved_data[1] в TX_response.ino) приходит значение 316!
Менять каналы пробовал, зашумлённость проверял. Не помогает.
Файлы проекта и библиотеки прикрепляю в архиве (ссылка на GDisk, ссылка на YaDisk).
P.S. Если код Вам покажется убогим и т.д., не кидайте тапками, я привык к написанию программ (для Windows) на Delphi (язык Object Pascal) и переучиваться на C-подобный язык мне сложно.
Сперва выкиньте Гивера с его библиотекой, потом вставьте сюда код по нормальному, не многие хотят таскать к себе зипы х.з. откуда.
Не используйте и проблем не будет.
А если уж невмоготу, то за консультациями ходите не сюда, а на специализированный форум: https://community.alexgyver.ru/
Ладно, фиг с ним с энкодером, может быть КОГДА-НИБУДЬ мне на форуме AlexGyver'а и ответят на этот вопрос.
Что не так с передачей/приёмом у nRF'ок? Привожу код ниже.
Код TX_response.ino:
001
#include <GyverEncoder.h>
002
#include <GyverButton.h>
003
#include <U8glib.h>
004
#include <SPI.h>
005
#include "Arduino.h"
006
#include "nRF24L01.h"
007
#include "RF24.h"
008
#include "printf.h"
009
// BtmpName Width x Height
010
#include "bat_lt.h" // BatLT 13 x 6
011
#include "bat_rc.h" // BatRC 13 x 6
012
#include "lt_big.h" // LtBig 12 x 11
013
#include "lt_big_on.h" // LtBigOn 10 x 9
014
#include "lt_big_sel.h" // LtBigSel 16 x 15
015
#include "lt_matt.h" // LtMatt 9 x 21
016
#include "lt_matt_on.h" // LtMattOn 7 x 7
017
#include "lt_matt_ref_sel.h" // LtMattRefSel 15 x 25
018
#include "lt_ref.h" // LtRef 9 x 21
019
#include "lt_ref_on.h" // LtRefOn 7 x 7
020
#include "sym_lt.h" // SymLT 10 x 6
021
#include "sym_rc.h" // SymRC 9 x 6
022
023
#define CH_NUM 0x70
024
#define SIG_POWER RF24_PA_HIGH
025
#define SIG_SPEED RF24_1MBPS
026
027
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
028
GButton butt1(5);
029
GButton butt2(6);
030
Encoder enc1(3, 2, 4);
031
RF24 radio(9, 10);
032
033
byte
address[][10] = {
"1Node"
,
"2Node"
,
"3Node"
,
"4Node"
,
"5Node"
,
"6Node"
,
"7Node"
,
"8Node"
,
"9Node"
,
"10Node"
};
034
byte
rssi;
035
byte
latest_data[6];
036
037
//float my_vcc_const = ;
038
039
#define vol_calibration 0 // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
040
float
my_vcc_const = 1.1;
// начальное значение константы должно быть 1.1
041
#include "EEPROMex.h"
042
043
char
mode[4]={0}, bright[4]={0};
044
045
boolean sleep =
false
, flag, select, sel_clk;
046
047
int
lgt_matt, lgt_matt_br, lgt_big, lgt_big_br, lgt_ref, lgt_ref_br, lgt_batt, lgt_on, lgt_sel, rc_batt, bright_mode, bright_var, V;
048
int
transmit_data[6];
049
int
recieved_data[1];
050
int
trnsmtd_pack = 1, failed_pack;
051
052
unsigned
long
RSSI_timer, currentTime, loopTime;
053
054
void
splash_screen(
void
) {
055
u8g.setFont(u8g_font_7x14B);
056
u8g.drawStr( 32, 26,
"Loading..."
);
057
}
058
059
void
light_is_off(
void
) {
060
u8g.setFont(u8g_font_7x14B);
061
u8g.drawStr( 3, 26,
"Main Light is Off!"
);
062
}
063
064
void
draw(
void
) {
065
u8g.drawXBMP( 0, 0, 13, 6, BatLT);
066
u8g.drawXBMP( 115, 0, 13, 6, BatRC);
067
u8g.drawXBMP( 17, 0, 10, 6, SymLT);
068
u8g.drawXBMP( 102, 0, 9, 6, SymRC);
069
u8g.drawXBMP( 40, 9, 9, 21, LtMatt);
070
u8g.drawXBMP( 79, 9, 9, 21, LtRef);
071
u8g.drawXBMP( 58, 2, 12, 11, LtBig);
072
u8g.setFont(u8g_font_7x14B);
073
u8g.drawStr( 1, 31,
"x"
);
074
u8g.setFont(u8g_font_9x15B);
075
u8g.drawStr( 12, 31, mode);
076
u8g.drawStr( 100, 31, bright);
077
if
(sel_clk ==
true
) u8g.drawStr( 60, 31,
"%"
);
078
if
(lgt_sel == 1) u8g.drawXBMP( 37, 7, 15, 25, LtMattRefSel);
079
if
(lgt_sel == 2) u8g.drawXBMP( 56, 0, 16, 15, LtBigSel);
080
if
(lgt_sel == 3) u8g.drawXBMP( 76, 7, 15, 25, LtMattRefSel);
081
if
(lgt_matt == 1) {
082
u8g.drawXBMP( 41, 10, 7, 7, LtMattOn);
083
u8g.drawXBMP( 41, 22, 7, 7, LtMattOn);
084
}
085
if
(lgt_big == 1) u8g.drawXBMP( 59, 3, 10, 9, LtBigOn);
086
if
(lgt_ref == 1) {
087
u8g.drawXBMP( 80, 10, 7, 7, LtRefOn);
088
u8g.drawXBMP( 80, 22, 7, 7, LtRefOn);
089
}
090
091
// LT Batt Lines
092
if
(lgt_batt > 5) {u8g.drawLine(1, 1, 1, 5);}
// 1-10
093
if
(lgt_batt > 10) {u8g.drawLine(2, 1, 2, 5);}
// 10-20
094
if
(lgt_batt > 20) {u8g.drawLine(3, 1, 3, 5);}
// 20-30
095
if
(lgt_batt > 30) {u8g.drawLine(4, 1, 4, 5);}
// 30-40
096
if
(lgt_batt > 40) {u8g.drawLine(5, 1, 5, 5);}
// 40-50
097
if
(lgt_batt > 50) {u8g.drawLine(6, 1, 6, 5);}
// 50-60
098
if
(lgt_batt > 60) {u8g.drawLine(7, 1, 7, 5);}
// 60-70
099
if
(lgt_batt > 70) {u8g.drawLine(8, 1, 8, 5);}
// 70-80
100
if
(lgt_batt > 80) {u8g.drawLine(9, 1, 9, 5);}
// 80-90
101
if
(lgt_batt > 90) {u8g.drawLine(10, 1, 10, 5);}
// 90-100
102
// RC Batt Lines
103
if
(rc_batt > 5) {u8g.drawLine(126, 1, 126, 5);}
// 1-10
104
if
(rc_batt > 10) {u8g.drawLine(125, 1, 125, 5);}
// 10-20
105
if
(rc_batt > 20) {u8g.drawLine(124, 1, 124, 5);}
// 20-30
106
if
(rc_batt > 30) {u8g.drawLine(123, 1, 123, 5);}
// 30-40
107
if
(rc_batt > 40) {u8g.drawLine(122, 1, 122, 5);}
// 40-50
108
if
(rc_batt > 50) {u8g.drawLine(121, 1, 121, 5);}
// 50-60
109
if
(rc_batt > 60) {u8g.drawLine(120, 1, 120, 5);}
// 60-70
110
if
(rc_batt > 70) {u8g.drawLine(119, 1, 119, 5);}
// 70-80
111
if
(rc_batt > 80) {u8g.drawLine(118, 1, 118, 5);}
// 80-90
112
if
(rc_batt > 90) {u8g.drawLine(117, 1, 117, 5);}
// 90-100
113
}
114
115
void
setup
() {
116
Serial
.begin(9600);
117
radioSetup();
118
delay(300);
119
butt1.setDebounce(90);
120
butt1.setTimeout(500);
121
butt1.setType(HIGH_PULL);
122
butt1.setDirection(NORM_OPEN);
123
butt1.setTickMode(AUTO);
124
butt2.setDebounce(90);
125
butt2.setTimeout(500);
126
butt2.setType(HIGH_PULL);
127
butt2.setDirection(NORM_OPEN);
128
butt2.setTickMode(AUTO);
129
// enc1.setType(TYPE1);
130
enc1.setTickMode(AUTO);
131
select =
false
;
132
bright_var = 100;
133
bright_mode = 10;
134
lgt_sel = 0;
135
lgt_ref = 0;
136
lgt_big = 0;
137
lgt_matt = 0;
138
lgt_ref_br = 100;
139
lgt_big_br = 100;
140
lgt_matt_br = 100;
141
sel_clk =
false
;
142
currentTime = millis();
143
loopTime = currentTime;
144
if
(vol_calibration) calibration();
// калибровка, если разрешена
145
my_vcc_const = EEPROM.readFloat(1000);
// считать константу из памяти
146
}
147
148
void
loop
() {
149
currentTime = millis();
150
151
//Serial.println(currentTime);
152
153
if
(currentTime >= (loopTime + 180000)) {
154
sleep =
true
;
155
}
156
157
if
(sleep ==
true
) {
158
u8g.sleepOn();
159
radio.powerDown();
160
if
(butt1.isClick() || butt2.isClick() || enc1.isRight() || enc1.isLeft() || enc1.isPress()){
161
sleep =
false
;
162
loopTime = currentTime;
163
radio.powerUp();
164
}
165
}
166
167
if
(sleep ==
false
) {
168
u8g.sleepOff();
169
170
if
(currentTime < 5000) {
171
transmit_data[0] = 1;
172
if
(radio.write(&transmit_data,
sizeof
(transmit_data))) {
173
trnsmtd_pack++;
174
if
(!radio.available()) {
175
}
else
{
176
while
(radio.available() ) {
177
radio.read(&recieved_data,
sizeof
(recieved_data));
178
lgt_on = recieved_data[0];
179
}
180
}
181
}
else
{
182
failed_pack++;
183
}
184
185
u8g.firstPage();
186
do
{
187
splash_screen();
188
}
while
( u8g.nextPage() );
189
190
}
191
192
if
(currentTime > 5500 && lgt_on == 0) {
193
u8g.firstPage();
194
do
{
195
light_is_off();
196
}
while
( u8g.nextPage() );
197
delay(4000);
198
}
199
200
if
(currentTime > 5500 && lgt_on == 1) {
201
202
lgt_on = 1;
203
204
V = analogRead(A0) * (readVcc() / 1023.0);
205
rc_batt = map(V, 2900, 4250, 0, 100);
206
207
if
(select ==
false
){
208
if
(enc1.isHolded()){
209
select =
true
;
210
lgt_sel = 1;
211
Serial
.println(
"Selection Mode ON"
);
212
Serial
.println(lgt_sel);
213
}
214
}
215
216
if
(select ==
true
){
217
218
if
(butt2.isClick()) {
219
if
(sel_clk ==
false
){
220
sel_clk =
true
;
221
Serial
.println(
"Selection Click Enable"
);
222
}
else
{
223
sel_clk =
false
;
224
Serial
.println(
"Selection Click Disable"
);
225
}
226
}
227
228
if
(sel_clk ==
false
){
229
if
(enc1.isTurn()) {
230
Serial
.println(
"Encoder Turn..."
);
231
}
232
233
if
(enc1.isRight()){ lgt_sel++;
234
Serial
.println(
"Right"
);
235
Serial
.println(lgt_sel);
236
}
237
if
(enc1.isLeft()){ lgt_sel--;
238
Serial
.println(
"Left"
);
239
Serial
.println(lgt_sel);
240
}
241
if
(lgt_sel > 3) lgt_sel = 1;
242
if
(lgt_sel < 1) lgt_sel = 3;
243
if
(enc1.isHolded()) {
244
select =
false
;
245
lgt_sel = 0;
246
Serial
.println(
"Selection Mode OFF"
);
247
Serial
.println(lgt_sel);
248
}
249
}
250
}
251
252
if
(sel_clk ==
true
){
253
if
(lgt_sel == 1) {
254
bright_var = lgt_matt_br;
255
if
(bright_mode == 1) {
256
if
(butt2.isHolded()) bright_mode = 10;
257
if
(enc1.isRight()) bright_var = bright_var + 1;
258
if
(enc1.isLeft()) bright_var = bright_var - 1;
259
bright_var = constrain(bright_var, 0, 100);
260
lgt_matt_br = bright_var;
261
}
else
{
262
if
(butt2.isHolded()) bright_mode = 1;
263
if
(enc1.isRight()) bright_var = bright_var + 10;
264
if
(enc1.isLeft()) bright_var = bright_var - 10;
265
bright_var = constrain(bright_var, 0, 100);
266
lgt_matt_br = bright_var;
267
}
268
if
(lgt_matt == 0) {
269
if
(butt1.isClick()) lgt_matt = 1;
270
}
else
{
271
if
(butt1.isClick()) lgt_matt = 0;
272
}
273
}
274
275
if
(lgt_sel == 2) {
276
bright_var = lgt_big_br;
277
if
(bright_mode == 1) {
278
if
(butt2.isHolded()) bright_mode = 10;
279
if
(enc1.isRight()) bright_var = bright_var + 1;
280
if
(enc1.isLeft()) bright_var = bright_var - 1;
281
bright_var = constrain(bright_var, 0, 100);
282
lgt_big_br = bright_var;
283
}
else
{
284
if
(butt2.isHolded()) bright_mode = 1;
285
if
(enc1.isRight()) bright_var = bright_var + 10;
286
if
(enc1.isLeft()) bright_var = bright_var - 10;
287
bright_var = constrain(bright_var, 0, 100);
288
lgt_big_br = bright_var;
289
}
290
if
(lgt_big == 0) {
291
if
(butt1.isClick()) lgt_big = 1;
292
}
else
{
293
if
(butt1.isClick()) lgt_big = 0;
294
}
295
}
296
297
if
(lgt_sel == 3) {
298
bright_var = lgt_ref_br;
299
if
(bright_mode == 1) {
300
if
(butt2.isHolded()) bright_mode = 10;
301
if
(enc1.isRight()) bright_var = bright_var + 1;
302
if
(enc1.isLeft()) bright_var = bright_var - 1;
303
bright_var = constrain(bright_var, 0, 100);
304
lgt_ref_br = bright_var;
305
}
else
{
306
if
(butt2.isHolded()) bright_mode = 1;
307
if
(enc1.isRight()) bright_var = bright_var + 10;
308
if
(enc1.isLeft()) bright_var = bright_var - 10;
309
bright_var = constrain(bright_var, 0, 100);
310
lgt_ref_br = bright_var;
311
}
312
if
(lgt_ref == 0) {
313
if
(butt1.isClick()) lgt_ref = 1;
314
}
else
{
315
if
(butt1.isClick()) lgt_ref = 0;
316
}
317
}
318
}
319
320
sprintf(mode,
"%02d"
, bright_mode);
321
sprintf(bright,
"%03d"
, bright_var);
322
323
transmit_data[0] = 1;
324
transmit_data[1] = lgt_ref;
325
transmit_data[2] = lgt_big;
326
transmit_data[3] = lgt_matt;
327
transmit_data[4] = lgt_ref_br;
328
transmit_data[5] = lgt_big_br;
329
transmit_data[6] = lgt_matt_br;
330
331
Serial
.println(lgt_matt_br);
332
333
if
(radio.write(&transmit_data,
sizeof
(transmit_data))) {
334
trnsmtd_pack++;
335
if
(!radio.available()) {
336
}
else
{
337
while
(radio.available() ) {
338
radio.read(&recieved_data,
sizeof
(recieved_data));
339
lgt_batt = recieved_data[1];
340
Serial
.println(lgt_batt);
341
}
342
}
343
}
else
{
344
failed_pack++;
345
}
346
347
348
u8g.firstPage();
349
do
{
350
draw();
351
}
while
( u8g.nextPage() );
352
353
354
355
356
if
(millis() - RSSI_timer > 1000) {
357
358
rssi = (1 - ((
float
)failed_pack / trnsmtd_pack)) * 100;
359
360
failed_pack = 0;
361
trnsmtd_pack = 0;
362
RSSI_timer = millis();
363
}
364
}
365
}
366
}
367
368
369
void
radioSetup() {
370
radio.begin();
371
radio.setAutoAck(1);
372
radio.setRetries(0, 15);
373
radio.enableAckPayload();
374
radio.setPayloadSize(32);
375
radio.openWritingPipe(address[0]);
376
radio.setChannel(CH_NUM);
377
radio.setPALevel(SIG_POWER);
378
radio.setDataRate(SIG_SPEED);
379
radio.powerUp();
380
radio.stopListening();
381
}
382
383
void
calibration() {
384
my_vcc_const = 1.1;
// начальаня константа калибровки
385
Serial
.print(
"Real VCC is: "
);
Serial
.println(readVcc());
// общаемся с пользователем
386
Serial
.println(
"Write your VCC (in millivolts)"
);
387
while
(
Serial
.available() == 0);
int
Vcc =
Serial
.parseInt();
// напряжение от пользователя
388
float
real_const = (
float
)1.1 * Vcc / readVcc();
// расчёт константы
389
Serial
.print(
"New voltage constant: "
);
Serial
.println(real_const, 3);
390
Serial
.println(
"Set vol_calibration 0, flash and enjoy!"
);
391
EEPROM.writeFloat(1000, real_const);
// запись в EEPROM
392
while
(1);
// уйти в бесконечный цикл
393
}
394
395
long
readVcc() {
396
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
397
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
398
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
399
ADMUX = _BV(MUX5) | _BV(MUX0);
400
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
401
ADMUX = _BV(MUX3) | _BV(MUX2);
402
#else
403
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
404
#endif
405
delay(2);
406
ADCSRA |= _BV(ADSC);
407
while
(bit_is_set(ADCSRA, ADSC));
408
uint8_t low = ADCL;
409
uint8_t high = ADCH;
410
long
result = (high << 8) | low;
411
result = my_vcc_const * 1023 * 1000 / result;
412
return
result;
413
}
Код RX_response.ino:
001
#include <SPI.h>
002
#include "nRF24L01.h"
003
#include "RF24.h"
004
#include "printf.h"
005
006
#define CH_NUM 0x70
007
#define SIG_POWER RF24_PA_MIN
008
#define SIG_SPEED RF24_1MBPS
009
010
RF24 radio(9, 10);
011
012
byte
pipeNo;
013
byte
address[][10] = {
"1Node"
,
"2Node"
,
"3Node"
,
"4Node"
,
"5Node"
,
"6Node"
,
"7Node"
,
"8Node"
,
"9Node"
,
"10Node"
};
014
015
int
recieved_data[6];
016
int
transmit_data[1];
017
018
int
V, Bat;
019
020
#define vol_calibration 0 // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
021
float
my_vcc_const = 1.1;
// начальное значение константы должно быть 1.1
022
#include "EEPROMex.h"
023
024
void
setup
() {
025
Serial
.begin(9600);
026
radioSetup();
027
delay(300);
028
pinMode(3, OUTPUT);
029
pinMode(5, OUTPUT);
030
pinMode(6, OUTPUT);
031
pinMode(7, OUTPUT);
032
analogWrite(3, 0);
033
analogWrite(5, 0);
034
analogWrite(6, 0);
035
digitalWrite(7, LOW);
036
if
(vol_calibration) calibration();
// калибровка, если разрешена
037
my_vcc_const = EEPROM.readFloat(1000);
// считать константу из памяти
038
}
039
040
void
loop
() {
041
V = analogRead(A0) * (readVcc() / 1023.0);
042
Bat = map(V, 2900, 4250, 0, 100);
043
044
while
(radio.available(&pipeNo)) {
045
radio.read( &recieved_data,
sizeof
(recieved_data));
046
047
transmit_data[0] = 1;
048
transmit_data[1] = Bat;
049
050
radio.writeAckPayload(pipeNo, &transmit_data,
sizeof
(transmit_data));
051
Serial
.println(Bat);
052
}
053
054
if
(recieved_data[1] == 1) {
055
analogWrite(3, map(recieved_data[4], 0, 100, 0, 255));
056
// Serial.println("LAMP 1");
057
Serial
.println(recieved_data[4]);
058
}
else
{
059
analogWrite(3, 0);
060
// Serial.println("LAMP 1 OFF");
061
}
062
063
if
(recieved_data[2] == 1) {
064
digitalWrite(7, HIGH);
065
analogWrite(5, map(recieved_data[5], 0, 100, 0, 255));
066
// Serial.println("LAMP 2");
067
Serial
.println(recieved_data[5]);
068
}
else
{
069
digitalWrite(7, LOW);
070
analogWrite(5, 0);
071
// Serial.println("LAMP 2 OFF");
072
}
073
074
if
(recieved_data[3] == 1) {
075
analogWrite(6, map(recieved_data[6], 0, 100, 0, 255));
076
Serial
.println(
"LAMP 3"
);
077
Serial
.println(recieved_data[6]);
078
Serial
.println(recieved_data[3]);
079
}
else
{
080
analogWrite(6, 0);
081
Serial
.println(
"LAMP 3 OFF"
);
082
}
083
084
}
085
086
void
radioSetup() {
087
radio.begin();
088
radio.setAutoAck(1);
089
radio.setRetries(0, 15);
090
radio.enableAckPayload();
091
radio.setPayloadSize(32);
092
radio.openReadingPipe(1, address[0]);
093
radio.setChannel(CH_NUM);
094
radio.setPALevel(SIG_POWER);
095
radio.setDataRate(SIG_SPEED);
096
radio.powerUp();
097
radio.startListening();
098
}
099
100
void
calibration() {
101
my_vcc_const = 1.1;
// начальаня константа калибровки
102
Serial
.print(
"Real VCC is: "
);
Serial
.println(readVcc());
// общаемся с пользователем
103
Serial
.println(
"Write your VCC (in millivolts)"
);
104
while
(
Serial
.available() == 0);
int
Vcc =
Serial
.parseInt();
// напряжение от пользователя
105
float
real_const = (
float
)1.1 * Vcc / readVcc();
// расчёт константы
106
Serial
.print(
"New voltage constant: "
);
Serial
.println(real_const, 3);
107
Serial
.println(
"Set vol_calibration 0, flash and enjoy!"
);
108
EEPROM.writeFloat(1000, real_const);
// запись в EEPROM
109
while
(1);
// уйти в бесконечный цикл
110
}
111
112
long
readVcc() {
113
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
114
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
115
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
116
ADMUX = _BV(MUX5) | _BV(MUX0);
117
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
118
ADMUX = _BV(MUX3) | _BV(MUX2);
119
#else
120
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
121
#endif
122
delay(2);
123
ADCSRA |= _BV(ADSC);
124
while
(bit_is_set(ADCSRA, ADSC));
125
uint8_t low = ADCL;
126
uint8_t high = ADCH;
127
long
result = (high << 8) | low;
128
result = my_vcc_const * 1023 * 1000 / result;
129
return
result;
130
}
nmm4evr - если у вас проблемы с передачей - самое правильное отладить прием-передачу отдельно от остального. Почистите код от всего лишнего. Код приемника и код передатчика NRF - это максимум 20 строк каждый, а не по 400 строк, не имющих ровно никакого отношения к радио
Что не так с передачей/приёмом у nRF'ок? Привожу код ниже.
Парень, ты только здесь так тупишь, или по жизни альтернативно одарённый?
Поясняю, медленно и громко: Вероятность того, что здесь кто-то прочитает код, начинающийся с
1
#include <Gyver...
дальше первой строки, практически неотличима от нуля.
Так понятно?
Тебе уже сказали, куда с этим кодом обратиться. Так зачем добиваться, чтобы в другие места посылать начали?
Вот! Убрал ВСЁ что не связано с nRF. Библиотеки AlexGyver'а к nRF ВООБЩЕ ни какого отношения не имеют, я их использовал только для кнопки и энкодера. ТАК ЛУЧШЕ?! И чем Вам AlexGyver не угодил? Удобные же у него библиотеки, не нужно писать километр кода (в котором я не слишком хорошо разбираюсь) в обвязку к кнопке или энкодеру чтобы всё работало нормально Б........
Вот очищеный код, который работает криво, а именно как, описано в первом посте темы.
001
#include <U8glib.h>
002
#include <SPI.h>
003
#include "Arduino.h"
004
#include "nRF24L01.h"
005
#include "RF24.h"
006
#include "printf.h"
007
// BtmpName Width x Height
008
#include "bat_lt.h" // BatLT 13 x 6
009
#include "bat_rc.h" // BatRC 13 x 6
010
#include "lt_big.h" // LtBig 12 x 11
011
#include "lt_big_on.h" // LtBigOn 10 x 9
012
#include "lt_big_sel.h" // LtBigSel 16 x 15
013
#include "lt_matt.h" // LtMatt 9 x 21
014
#include "lt_matt_on.h" // LtMattOn 7 x 7
015
#include "lt_matt_ref_sel.h" // LtMattRefSel 15 x 25
016
#include "lt_ref.h" // LtRef 9 x 21
017
#include "lt_ref_on.h" // LtRefOn 7 x 7
018
#include "sym_lt.h" // SymLT 10 x 6
019
#include "sym_rc.h" // SymRC 9 x 6
020
021
#define CH_NUM 0x70
022
#define SIG_POWER RF24_PA_HIGH
023
#define SIG_SPEED RF24_1MBPS
024
025
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
026
RF24 radio(9, 10);
027
028
byte
address[][10] = {
"1Node"
,
"2Node"
,
"3Node"
,
"4Node"
,
"5Node"
,
"6Node"
,
"7Node"
,
"8Node"
,
"9Node"
,
"10Node"
};
029
byte
rssi;
030
byte
latest_data[6];
031
032
//float my_vcc_const = ;
033
034
#define vol_calibration 0 // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
035
float
my_vcc_const = 1.1;
// начальное значение константы должно быть 1.1
036
#include "EEPROMex.h"
037
038
char
mode[4]={0}, bright[4]={0};
039
040
boolean sleep =
false
, flag, select, sel_clk;
041
042
int
lgt_matt, lgt_matt_br, lgt_big, lgt_big_br, lgt_ref, lgt_ref_br, lgt_batt, lgt_on, lgt_sel, rc_batt, bright_mode, bright_var, V;
043
int
transmit_data[6];
044
int
recieved_data[1];
045
int
trnsmtd_pack = 1, failed_pack;
046
047
unsigned
long
RSSI_timer, currentTime, loopTime;
048
049
void
splash_screen(
void
) {
050
u8g.setFont(u8g_font_7x14B);
051
u8g.drawStr( 32, 26,
"Loading..."
);
052
}
053
054
void
light_is_off(
void
) {
055
u8g.setFont(u8g_font_7x14B);
056
u8g.drawStr( 3, 26,
"Main Light is Off!"
);
057
}
058
059
void
draw(
void
) {
060
u8g.drawXBMP( 0, 0, 13, 6, BatLT);
061
u8g.drawXBMP( 115, 0, 13, 6, BatRC);
062
u8g.drawXBMP( 17, 0, 10, 6, SymLT);
063
u8g.drawXBMP( 102, 0, 9, 6, SymRC);
064
u8g.drawXBMP( 40, 9, 9, 21, LtMatt);
065
u8g.drawXBMP( 79, 9, 9, 21, LtRef);
066
u8g.drawXBMP( 58, 2, 12, 11, LtBig);
067
u8g.setFont(u8g_font_7x14B);
068
u8g.drawStr( 1, 31,
"x"
);
069
u8g.setFont(u8g_font_9x15B);
070
u8g.drawStr( 12, 31, mode);
071
u8g.drawStr( 100, 31, bright);
072
if
(sel_clk ==
true
) u8g.drawStr( 60, 31,
"%"
);
073
if
(lgt_sel == 1) u8g.drawXBMP( 37, 7, 15, 25, LtMattRefSel);
074
if
(lgt_sel == 2) u8g.drawXBMP( 56, 0, 16, 15, LtBigSel);
075
if
(lgt_sel == 3) u8g.drawXBMP( 76, 7, 15, 25, LtMattRefSel);
076
if
(lgt_matt == 1) {
077
u8g.drawXBMP( 41, 10, 7, 7, LtMattOn);
078
u8g.drawXBMP( 41, 22, 7, 7, LtMattOn);
079
}
080
if
(lgt_big == 1) u8g.drawXBMP( 59, 3, 10, 9, LtBigOn);
081
if
(lgt_ref == 1) {
082
u8g.drawXBMP( 80, 10, 7, 7, LtRefOn);
083
u8g.drawXBMP( 80, 22, 7, 7, LtRefOn);
084
}
085
086
// LT Batt Lines
087
if
(lgt_batt > 5) {u8g.drawLine(1, 1, 1, 5);}
// 1-10
088
if
(lgt_batt > 10) {u8g.drawLine(2, 1, 2, 5);}
// 10-20
089
if
(lgt_batt > 20) {u8g.drawLine(3, 1, 3, 5);}
// 20-30
090
if
(lgt_batt > 30) {u8g.drawLine(4, 1, 4, 5);}
// 30-40
091
if
(lgt_batt > 40) {u8g.drawLine(5, 1, 5, 5);}
// 40-50
092
if
(lgt_batt > 50) {u8g.drawLine(6, 1, 6, 5);}
// 50-60
093
if
(lgt_batt > 60) {u8g.drawLine(7, 1, 7, 5);}
// 60-70
094
if
(lgt_batt > 70) {u8g.drawLine(8, 1, 8, 5);}
// 70-80
095
if
(lgt_batt > 80) {u8g.drawLine(9, 1, 9, 5);}
// 80-90
096
if
(lgt_batt > 90) {u8g.drawLine(10, 1, 10, 5);}
// 90-100
097
// RC Batt Lines
098
if
(rc_batt > 5) {u8g.drawLine(126, 1, 126, 5);}
// 1-10
099
if
(rc_batt > 10) {u8g.drawLine(125, 1, 125, 5);}
// 10-20
100
if
(rc_batt > 20) {u8g.drawLine(124, 1, 124, 5);}
// 20-30
101
if
(rc_batt > 30) {u8g.drawLine(123, 1, 123, 5);}
// 30-40
102
if
(rc_batt > 40) {u8g.drawLine(122, 1, 122, 5);}
// 40-50
103
if
(rc_batt > 50) {u8g.drawLine(121, 1, 121, 5);}
// 50-60
104
if
(rc_batt > 60) {u8g.drawLine(120, 1, 120, 5);}
// 60-70
105
if
(rc_batt > 70) {u8g.drawLine(119, 1, 119, 5);}
// 70-80
106
if
(rc_batt > 80) {u8g.drawLine(118, 1, 118, 5);}
// 80-90
107
if
(rc_batt > 90) {u8g.drawLine(117, 1, 117, 5);}
// 90-100
108
}
109
110
void
setup
() {
111
Serial
.begin(9600);
112
radioSetup();
113
delay(300);
114
select =
false
;
115
bright_var = 100;
116
bright_mode = 10;
117
lgt_sel = 0;
118
lgt_ref = 0;
119
lgt_big = 0;
120
lgt_matt = 0;
121
lgt_ref_br = 100;
122
lgt_big_br = 100;
123
lgt_matt_br = 100;
124
sel_clk =
false
;
125
currentTime = millis();
126
loopTime = currentTime;
127
if
(vol_calibration) calibration();
// калибровка, если разрешена
128
my_vcc_const = EEPROM.readFloat(1000);
// считать константу из памяти
129
}
130
131
void
loop
() {
132
currentTime = millis();
133
134
//Serial.println(currentTime);
135
136
if
(currentTime >= (loopTime + 180000)) {
137
sleep =
true
;
138
}
139
140
if
(sleep ==
true
) {
141
u8g.sleepOn();
142
radio.powerDown();
143
if
(Нажатие кнопки или поворот энкодера){
144
sleep =
false
;
145
loopTime = currentTime;
146
radio.powerUp();
147
}
148
}
149
150
if
(sleep ==
false
) {
151
u8g.sleepOff();
152
153
if
(currentTime < 5000) {
154
transmit_data[0] = 1;
155
if
(radio.write(&transmit_data,
sizeof
(transmit_data))) {
156
trnsmtd_pack++;
157
if
(!radio.available()) {
158
}
else
{
159
while
(radio.available() ) {
160
radio.read(&recieved_data,
sizeof
(recieved_data));
161
lgt_on = recieved_data[0];
162
}
163
}
164
}
else
{
165
failed_pack++;
166
}
167
168
u8g.firstPage();
169
do
{
170
splash_screen();
171
}
while
( u8g.nextPage() );
172
173
}
174
175
if
(currentTime > 5500 && lgt_on == 0) {
176
u8g.firstPage();
177
do
{
178
light_is_off();
179
}
while
( u8g.nextPage() );
180
delay(4000);
181
}
182
183
if
(currentTime > 5500 && lgt_on == 1) {
184
185
lgt_on = 1;
186
187
V = analogRead(A0) * (readVcc() / 1023.0);
188
rc_batt = map(V, 2900, 4250, 0, 100);
189
190
191
sprintf(mode,
"%02d"
, bright_mode);
192
sprintf(bright,
"%03d"
, bright_var);
193
194
transmit_data[0] = 1;
195
transmit_data[1] = lgt_ref;
196
transmit_data[2] = lgt_big;
197
transmit_data[3] = lgt_matt;
198
transmit_data[4] = lgt_ref_br;
199
transmit_data[5] = lgt_big_br;
200
transmit_data[6] = lgt_matt_br;
201
202
Serial
.println(lgt_matt_br);
203
204
if
(radio.write(&transmit_data,
sizeof
(transmit_data))) {
205
trnsmtd_pack++;
206
if
(!radio.available()) {
207
}
else
{
208
while
(radio.available() ) {
209
radio.read(&recieved_data,
sizeof
(recieved_data));
210
lgt_batt = recieved_data[1];
211
Serial
.println(lgt_batt);
212
}
213
}
214
}
else
{
215
failed_pack++;
216
}
217
218
219
u8g.firstPage();
220
do
{
221
draw();
222
}
while
( u8g.nextPage() );
223
224
225
226
227
if
(millis() - RSSI_timer > 1000) {
228
229
rssi = (1 - ((
float
)failed_pack / trnsmtd_pack)) * 100;
230
231
failed_pack = 0;
232
trnsmtd_pack = 0;
233
RSSI_timer = millis();
234
}
235
}
236
}
237
}
238
239
240
void
radioSetup() {
241
radio.begin();
242
radio.setAutoAck(1);
243
radio.setRetries(0, 15);
244
radio.enableAckPayload();
245
radio.setPayloadSize(32);
246
radio.openWritingPipe(address[0]);
247
radio.setChannel(CH_NUM);
248
radio.setPALevel(SIG_POWER);
249
radio.setDataRate(SIG_SPEED);
250
radio.powerUp();
251
radio.stopListening();
252
}
253
254
void
calibration() {
255
my_vcc_const = 1.1;
256
Serial
.print(
"Real VCC is: "
);
Serial
.println(readVcc());
257
Serial
.println(
"Write your VCC (in millivolts)"
);
258
while
(
Serial
.available() == 0);
int
Vcc =
Serial
.parseInt();
259
float
real_const = (
float
)1.1 * Vcc / readVcc();
260
Serial
.print(
"New voltage constant: "
);
Serial
.println(real_const, 3);
261
Serial
.println(
"Set vol_calibration 0, flash and enjoy!"
);
262
EEPROM.writeFloat(1000, real_const);
263
while
(1);
264
}
265
266
long
readVcc() {
267
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
268
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
269
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
270
ADMUX = _BV(MUX5) | _BV(MUX0);
271
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
272
ADMUX = _BV(MUX3) | _BV(MUX2);
273
#else
274
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
275
#endif
276
delay(2);
277
ADCSRA |= _BV(ADSC);
278
while
(bit_is_set(ADCSRA, ADSC));
279
uint8_t low = ADCL;
280
uint8_t high = ADCH;
281
long
result = (high << 8) | low;
282
result = my_vcc_const * 1023 * 1000 / result;
283
return
result;
284
}
И чем Вам AlexGyver не угодил? Удобные же у него библиотеки, не нужно писать километр кода (в котором я не слишком хорошо разбираюсь) в обвязку к кнопке или энкодеру чтобы всё работало нормально Б........
Они может и удобные, только сильно глючные, а приводить их в порядок он не собирается.
Вот! Убрал ВСЁ что не связано с nRF.
Вранье!
из оставшихся 250 (или сколько там) строк - 200 это вывод на экран известной своими заморочками либы U8glib, которая легко может имитировать неработоспособность NRF
вы плохо понимаете? - 20 строк оставьте! а не 200
А кто тебе сказал, что с его библиотеками всё работает нормально? Вот у тебя не работает, и таких как ты тут знаешь сколько ходит? Вот, и на других форумах пострадавшие имеются.
Я лично не видел ни одной его библиотеки, в которой не было бы откровенных ляпов. Ни одной!
Он тут как-то выложил кучу своих библиотек. Ему показали явные и скрытые ошибки. Например: #3, #26, #29, #31, #52, #67.
А вот теперь, полезь и посмотри, сколько из них он поправил, а сколько так и остались ляпами.
Нет
Тоже нет
Вы сами признались, что в программировании не очень, но упорно спорите с людьми, знающими о нем на порядок или даже на пару больше
каким образом библиотека для передачи изображения на дисплей может влиять на библиотеку для передачи данных через nRF'ки?
В условиях ограниченности ресурсов - а для программирования МК это норма - легко может влиять. Нехватка памяти, работа двух библиотек с одним и тем же таймеров, конфликт прерываний, некорректное обращение к периферии...
Ваша задача при отладке - максимально отделить влияние одной библиотеки от другой. Впрочем, если вы уверены, что знаете более простой и легкий путь найти ошибки - ищите сами.
Избавился от библиотек от AlexGyver.
С nRF24L01+ более-менее разобрался просто добавив в массив ещё одно значение и записав туда ноль, может оно и считывается/передается с глюками, но зато все остальные значения массива теперь передаются нормально и то хорошо.
Но вот с энкодером все равно ни чего не получается, ну вот не работает он и ВСЁ тут, кнопки работают и кнопка энкодера тоже, я уже даже конденсаторы на 100 нФ припаял чтобы дребезги на энкодере убрать, вот в примере того что я щас использую вместо GyverEncoder всё работает, в моём коде не работает ни в какую.
Прикладываю код примера и код TX_response.
TX_response:
001
#include <U8glib.h>
002
#include <SPI.h>
003
#include "Arduino.h"
004
#include "nRF24L01.h"
005
#include "RF24.h"
006
#include "printf.h"
007
#include "sav_button.h"
008
// BtmpName Width x Height
009
#include "bat_lt.h" // BatLT 13 x 6
010
#include "bat_rc.h" // BatRC 13 x 6
011
#include "lt_big.h" // LtBig 12 x 11
012
#include "lt_big_on.h" // LtBigOn 10 x 9
013
#include "lt_big_sel.h" // LtBigSel 16 x 15
014
#include "lt_matt.h" // LtMatt 9 x 21
015
#include "lt_matt_on.h" // LtMattOn 7 x 7
016
#include "lt_matt_ref_sel.h" // LtMattRefSel 15 x 25
017
#include "lt_ref.h" // LtRef 9 x 21
018
#include "lt_ref_on.h" // LtRefOn 7 x 7
019
#include "sym_lt.h" // SymLT 10 x 6
020
#include "sym_rc.h" // SymRC 9 x 6
021
022
#define CH_NUM 0x70
023
#define SIG_POWER RF24_PA_HIGH
024
#define SIG_SPEED RF24_1MBPS
025
#define pin_CLK 2
026
#define pin_DT 3
027
#define pin_Btn 7
028
029
SButton button1(4,50,2000,0,1000);
030
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
031
RF24 radio(9, 10);
032
033
byte
address[][10] = {
"1Node"
,
"2Node"
,
"3Node"
,
"4Node"
,
"5Node"
,
"6Node"
,
"7Node"
,
"8Node"
,
"9Node"
,
"10Node"
};
034
//byte rssi;
035
byte
latest_data[6];
036
037
#define vol_calibration 0 // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
038
float
my_vcc_const = 1.1;
// начальное значение константы должно быть 1.1
039
#include "EEPROMex.h"
040
041
char
mode[4]={0}, bright[4]={0};
042
043
boolean sleep =
false
, flag, select, sel_clk, ButtonPrev;
044
045
const
int
butt1Pin = 5;
046
const
int
butt2Pin = 6;
047
048
int
lgt_matt, lgt_matt_br, lgt_big, lgt_big_br, lgt_ref, lgt_ref_br, lgt_batt, lgt_on, lgt_sel, rc_batt, bright_mode, bright_var, V;
049
int
transmit_data[7];
050
int
recieved_data[2];
051
int
EncoderA, EncoderB, EncoderAPrev, butt1 = 0, butt2 = 0;
052
//int trnsmtd_pack = 1, failed_pack;
053
054
unsigned
long
RSSI_timer, currentTime, loopTime, CurrTime, LastTime;
055
056
enum
eEncoderState {eNone, eLeft, eRight, eButton};
057
058
void
splash_screen(
void
) {
059
u8g.setFont(u8g_font_7x14B);
060
u8g.drawStr( 32, 26,
"Loading..."
);
061
}
062
063
void
light_is_off(
void
) {
064
u8g.setFont(u8g_font_7x14B);
065
u8g.drawStr( 3, 26,
"Main Light is Off!"
);
066
}
067
068
void
draw(
void
) {
069
u8g.drawXBMP( 0, 0, 13, 6, BatLT);
070
u8g.drawXBMP( 115, 0, 13, 6, BatRC);
071
u8g.drawXBMP( 17, 0, 10, 6, SymLT);
072
u8g.drawXBMP( 102, 0, 9, 6, SymRC);
073
u8g.drawXBMP( 40, 9, 9, 21, LtMatt);
074
u8g.drawXBMP( 79, 9, 9, 21, LtRef);
075
u8g.drawXBMP( 58, 2, 12, 11, LtBig);
076
u8g.setFont(u8g_font_7x14B);
077
u8g.drawStr( 1, 31,
"x"
);
078
u8g.setFont(u8g_font_9x15B);
079
u8g.drawStr( 12, 31, mode);
080
u8g.drawStr( 100, 31, bright);
081
if
(sel_clk ==
true
) u8g.drawStr( 60, 31,
"%"
);
082
if
(lgt_sel == 1) u8g.drawXBMP( 37, 7, 15, 25, LtMattRefSel);
083
if
(lgt_sel == 2) u8g.drawXBMP( 56, 0, 16, 15, LtBigSel);
084
if
(lgt_sel == 3) u8g.drawXBMP( 76, 7, 15, 25, LtMattRefSel);
085
if
(lgt_matt == 1) {
086
u8g.drawXBMP( 41, 10, 7, 7, LtMattOn);
087
u8g.drawXBMP( 41, 22, 7, 7, LtMattOn);
088
}
089
if
(lgt_big == 1) u8g.drawXBMP( 59, 3, 10, 9, LtBigOn);
090
if
(lgt_ref == 1) {
091
u8g.drawXBMP( 80, 10, 7, 7, LtRefOn);
092
u8g.drawXBMP( 80, 22, 7, 7, LtRefOn);
093
}
094
095
// LT Batt Lines
096
if
(lgt_batt > 5) {u8g.drawLine(1, 1, 1, 5);}
// 1-10
097
if
(lgt_batt > 10) {u8g.drawLine(2, 1, 2, 5);}
// 10-20
098
if
(lgt_batt > 20) {u8g.drawLine(3, 1, 3, 5);}
// 20-30
099
if
(lgt_batt > 30) {u8g.drawLine(4, 1, 4, 5);}
// 30-40
100
if
(lgt_batt > 40) {u8g.drawLine(5, 1, 5, 5);}
// 40-50
101
if
(lgt_batt > 50) {u8g.drawLine(6, 1, 6, 5);}
// 50-60
102
if
(lgt_batt > 60) {u8g.drawLine(7, 1, 7, 5);}
// 60-70
103
if
(lgt_batt > 70) {u8g.drawLine(8, 1, 8, 5);}
// 70-80
104
if
(lgt_batt > 80) {u8g.drawLine(9, 1, 9, 5);}
// 80-90
105
if
(lgt_batt > 90) {u8g.drawLine(10, 1, 10, 5);}
// 90-100
106
// RC Batt Lines
107
if
(rc_batt > 5) {u8g.drawLine(126, 1, 126, 5);}
// 1-10
108
if
(rc_batt > 10) {u8g.drawLine(125, 1, 125, 5);}
// 10-20
109
if
(rc_batt > 20) {u8g.drawLine(124, 1, 124, 5);}
// 20-30
110
if
(rc_batt > 30) {u8g.drawLine(123, 1, 123, 5);}
// 30-40
111
if
(rc_batt > 40) {u8g.drawLine(122, 1, 122, 5);}
// 40-50
112
if
(rc_batt > 50) {u8g.drawLine(121, 1, 121, 5);}
// 50-60
113
if
(rc_batt > 60) {u8g.drawLine(120, 1, 120, 5);}
// 60-70
114
if
(rc_batt > 70) {u8g.drawLine(119, 1, 119, 5);}
// 70-80
115
if
(rc_batt > 80) {u8g.drawLine(118, 1, 118, 5);}
// 80-90
116
if
(rc_batt > 90) {u8g.drawLine(117, 1, 117, 5);}
// 90-100
117
}
118
119
eEncoderState GetEncoderState() {
120
// Считываем состояние энкодера
121
eEncoderState Result = eNone;
122
CurrTime = millis();
123
if
(CurrTime >= (LastTime + 5)) {
124
// Считываем не чаще 1 раза в 5 мс для уменьшения ложных срабатываний
125
LastTime = CurrTime;
126
if
(digitalRead(pin_Btn) == LOW ) {
127
if
(ButtonPrev) {
128
Result = eButton;
// Нажата кнопка
129
ButtonPrev = 0;
130
}
131
}
132
else
{
133
ButtonPrev = 1;
134
EncoderA = digitalRead(pin_DT);
135
EncoderB = digitalRead(pin_CLK);
136
if
((!EncoderA) && (EncoderAPrev)) {
// Сигнал A изменился с 1 на 0
137
if
(EncoderB) Result = eRight;
// B=1 => энкодер вращается по часовой
138
else
Result = eLeft;
// B=0 => энкодер вращается против часовой
139
}
140
EncoderAPrev = EncoderA;
// запомним текущее состояние
141
}
142
}
143
return
Result;
144
}
145
146
void
setup
() {
147
Serial
.begin(9600);
148
radioSetup();
149
delay(300);
150
pinMode(butt1Pin, INPUT);
151
pinMode(butt2Pin, INPUT);
152
button1.begin();
153
pinMode(pin_DT, INPUT);
154
pinMode(pin_CLK, INPUT);
155
pinMode(pin_Btn, INPUT_PULLUP);
156
select =
false
;
157
bright_var = 100;
158
bright_mode = 10;
159
lgt_sel = 0;
160
lgt_ref = 0;
161
lgt_big = 0;
162
lgt_matt = 0;
163
lgt_ref_br = 100;
164
lgt_big_br = 100;
165
lgt_matt_br = 100;
166
sel_clk =
false
;
167
currentTime = millis();
168
loopTime = currentTime;
169
if
(vol_calibration) calibration();
// калибровка, если разрешена
170
my_vcc_const = EEPROM.readFloat(1000);
// считать константу из памяти
171
}
172
173
void
loop
() {
174
currentTime = millis();
175
176
if
(currentTime >= (loopTime + 180000)) {
177
sleep =
true
;
178
}
179
// Режим сна
180
if
(sleep ==
true
) {
181
u8g.sleepOn();
182
radio.powerDown();
183
// Выход из режима сна
184
if
(butt1 == HIGH || butt2 == HIGH || button1.Loop() == SB_CLICK || GetEncoderState() == eLeft || GetEncoderState() == eRight){
185
sleep =
false
;
186
loopTime = currentTime;
187
radio.powerUp();
188
}
189
190
}
191
// Обычный режим или первый запуск
192
if
(sleep ==
false
) {
193
u8g.sleepOff();
194
// Надпись Loading... и ожидание отклика "Люстры"
195
if
(currentTime < 5000) {
196
transmit_data[0] = 1;
197
if
(radio.write(&transmit_data,
sizeof
(transmit_data))) {
198
// trnsmtd_pack++;
199
if
(!radio.available()) {
200
}
else
{
201
while
(radio.available() ) {
202
radio.read(&recieved_data,
sizeof
(recieved_data));
203
lgt_on = recieved_data[0];
204
}
205
}
206
}
else
{
207
// failed_pack++;
208
}
209
210
u8g.firstPage();
211
do
{
212
splash_screen();
213
}
while
( u8g.nextPage() );
214
215
}
216
// Отклик от "Люстры" НЕ получен, сообщаем об этом
217
if
(currentTime > 5500 && lgt_on == 0) {
218
u8g.firstPage();
219
do
{
220
light_is_off();
221
}
while
( u8g.nextPage() );
222
delay(4000);
223
}
224
// Отклик от "Люстры" получен, переходим в рабочий режим
225
if
(currentTime > 5500 && lgt_on == 1) {
226
227
//lgt_on = 1;
228
//
229
butt1 = digitalRead(butt1Pin);
230
butt2 = digitalRead(butt2Pin);
231
//
232
V = analogRead(A0) * (readVcc() / 1023.0);
233
rc_batt = map(V, 2950, 4100, 0, 100);
234
//
235
if
(select ==
false
){
236
if
(button1.Loop() == SB_LONG_CLICK){
237
// delay(600);
238
Serial
.println(
"Selection Mode ON"
);
239
select =
true
;
240
lgt_sel = 1;
241
Serial
.println(lgt_sel);
242
}
243
}
244
//
245
if
(select ==
true
){
246
247
if
(butt2 == HIGH) {
248
delay(300);
249
if
(sel_clk ==
false
){
250
sel_clk =
true
;
251
Serial
.println(
"Selection Click Enable"
);
252
}
else
{
253
sel_clk =
false
;
254
Serial
.println(
"Selection Click Disable"
);
255
}
256
}
257
//
258
if
(sel_clk ==
false
){
259
260
if
(GetEncoderState() == eRight){
261
lgt_sel++;
262
Serial
.println(
"Right"
);
263
Serial
.println(lgt_sel);
264
}
265
if
(GetEncoderState() == eLeft){
266
lgt_sel--;
267
Serial
.println(
"Left"
);
268
Serial
.println(lgt_sel);
269
}
270
if
(lgt_sel > 3) lgt_sel = 1;
271
if
(lgt_sel < 1) lgt_sel = 3;
272
//
273
if
(button1.Loop() == SB_LONG_CLICK) {
274
select =
false
;
275
lgt_sel = 0;
276
Serial
.println(
"Selection Mode OFF"
);
277
Serial
.println(lgt_sel);
278
}
279
}
280
}
281
//
282
if
(sel_clk ==
true
){
283
//
284
if
(lgt_sel == 1) {
285
bright_var = lgt_matt_br;
286
if
(bright_mode == 1) {
287
if
(butt1 == HIGH && butt2 == HIGH) bright_mode = 10;
288
if
(GetEncoderState() == eRight) bright_var = bright_var + 1;
289
if
(GetEncoderState() == eLeft) bright_var = bright_var - 1;
290
bright_var = constrain(bright_var, 0, 100);
291
lgt_matt_br = bright_var;
292
}
else
{
293
if
(butt1 == HIGH && butt2 == HIGH) bright_mode = 1;
294
if
(GetEncoderState() == eRight) bright_var = bright_var + 10;
295
if
(GetEncoderState() == eLeft) bright_var = bright_var - 10;
296
bright_var = constrain(bright_var, 0, 100);
297
lgt_matt_br = bright_var;
298
}
299
if
(lgt_matt == 0) {
300
if
(butt1 == HIGH) {
301
delay(150);
302
lgt_matt = 1;
303
}
304
}
else
{
305
if
(butt1 == HIGH){
306
delay(150);
307
lgt_matt = 0;
308
}
309
}
310
}
311
//
312
if
(lgt_sel == 2) {
313
bright_var = lgt_big_br;
314
if
(bright_mode == 1) {
315
if
(butt1 == HIGH && butt2 == HIGH) bright_mode = 10;
316
if
(GetEncoderState() == eRight) bright_var = bright_var + 1;
317
if
(GetEncoderState() == eLeft) bright_var = bright_var - 1;
318
bright_var = constrain(bright_var, 0, 100);
319
lgt_big_br = bright_var;
320
}
else
{
321
if
(butt1 == HIGH && butt2 == HIGH) bright_mode = 1;
322
if
(GetEncoderState() == eRight) bright_var = bright_var + 10;
323
if
(GetEncoderState() == eLeft) bright_var = bright_var - 10;
324
bright_var = constrain(bright_var, 0, 100);
325
lgt_big_br = bright_var;
326
}
327
if
(lgt_big == 0) {
328
if
(butt1 == HIGH) {
329
delay(150);
330
lgt_big = 1;
331
}
332
}
else
{
333
if
(butt1 == HIGH) {
334
delay(150);
335
lgt_big = 0;
336
}
337
}
338
}
339
//
340
if
(lgt_sel == 3) {
341
bright_var = lgt_ref_br;
342
if
(bright_mode == 1) {
343
if
(butt1 == HIGH && butt2 == HIGH) bright_mode = 10;
344
if
(GetEncoderState() == eRight) bright_var = bright_var + 1;
345
if
(GetEncoderState() == eLeft) bright_var = bright_var - 1;
346
bright_var = constrain(bright_var, 0, 100);
347
lgt_ref_br = bright_var;
348
}
else
{
349
if
(butt1 == HIGH && butt2 == HIGH) bright_mode = 1;
350
if
(GetEncoderState() == eRight) bright_var = bright_var + 10;
351
if
(GetEncoderState() == eLeft) bright_var = bright_var - 10;
352
bright_var = constrain(bright_var, 0, 100);
353
lgt_ref_br = bright_var;
354
}
355
if
(lgt_ref == 0) {
356
if
(butt1 == HIGH){
357
delay(150);
358
lgt_ref = 1;
359
}
360
}
else
{
361
if
(butt1 == HIGH) {
362
delay(150);
363
lgt_ref = 0;
364
}
365
}
366
}
367
}
368
//
369
sprintf(mode,
"%02d"
, bright_mode);
370
sprintf(bright,
"%03d"
, bright_var);
371
//
372
transmit_data[0] = 1;
373
transmit_data[1] = lgt_ref;
374
transmit_data[2] = lgt_big;
375
transmit_data[3] = lgt_matt;
376
transmit_data[4] = lgt_ref_br;
377
transmit_data[5] = lgt_big_br;
378
transmit_data[6] = lgt_matt_br;
379
transmit_data[7] = 0;
380
381
if
(radio.write(&transmit_data,
sizeof
(transmit_data))) {
382
// trnsmtd_pack++;
383
if
(!radio.available()) {
384
}
else
{
385
while
(radio.available() ) {
386
radio.read(&recieved_data,
sizeof
(recieved_data));
387
lgt_batt = recieved_data[1];
388
}
389
}
390
}
else
{
391
// failed_pack++;
392
}
393
394
//
395
u8g.firstPage();
396
do
{
397
draw();
398
}
while
( u8g.nextPage() );
399
400
}
401
}
402
}
403
404
405
void
radioSetup() {
406
radio.begin();
407
radio.setAutoAck(1);
408
radio.setRetries(0, 15);
409
radio.enableAckPayload();
410
radio.setPayloadSize(32);
411
radio.openWritingPipe(address[0]);
412
radio.setChannel(CH_NUM);
413
radio.setPALevel(SIG_POWER);
414
radio.setDataRate(SIG_SPEED);
415
radio.powerUp();
416
radio.stopListening();
417
}
418
419
void
calibration() {
420
my_vcc_const = 1.1;
// начальаня константа калибровки
421
Serial
.print(
"Real VCC is: "
);
Serial
.println(readVcc());
// общаемся с пользователем
422
Serial
.println(
"Write your VCC (in millivolts)"
);
423
while
(
Serial
.available() == 0);
int
Vcc =
Serial
.parseInt();
// напряжение от пользователя
424
float
real_const = (
float
)1.1 * Vcc / readVcc();
// расчёт константы
425
Serial
.print(
"New voltage constant: "
);
Serial
.println(real_const, 3);
426
Serial
.println(
"Set vol_calibration 0, flash and enjoy!"
);
427
EEPROM.writeFloat(1000, real_const);
// запись в EEPROM
428
while
(1);
// уйти в бесконечный цикл
429
}
430
431
long
readVcc() {
432
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
433
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
434
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
435
ADMUX = _BV(MUX5) | _BV(MUX0);
436
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
437
ADMUX = _BV(MUX3) | _BV(MUX2);
438
#else
439
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
440
#endif
441
delay(2);
442
ADCSRA |= _BV(ADSC);
443
while
(bit_is_set(ADCSRA, ADSC));
444
uint8_t low = ADCL;
445
uint8_t high = ADCH;
446
long
result = (high << 8) | low;
447
result = my_vcc_const * 1023 * 1000 / result;
448
return
result;
449
}
Пример для энкодера:
01
#define pin_CLK 3
02
#define pin_DT 2
03
#define pin_Btn 4
04
05
unsigned
long
CurrTime, LastTime;
06
enum
eEncoderState {eNone, eLeft, eRight, eButton};
07
int
EncoderA, EncoderB, EncoderAPrev, counter;
08
bool
ButtonPrev;
09
10
eEncoderState GetEncoderState() {
11
// Считываем состояние энкодера
12
eEncoderState Result = eNone;
13
CurrTime = millis();
14
if
(CurrTime >= (LastTime + 5)) {
15
// Считываем не чаще 1 раза в 5 мс для уменьшения ложных срабатываний
16
LastTime = CurrTime;
17
if
(digitalRead(pin_Btn) == LOW ) {
18
if
(ButtonPrev) {
19
Result = eButton;
// Нажата кнопка
20
ButtonPrev = 0;
21
}
22
}
23
else
{
24
ButtonPrev = 1;
25
EncoderA = digitalRead(pin_DT);
26
EncoderB = digitalRead(pin_CLK);
27
if
((!EncoderA) && (EncoderAPrev)) {
// Сигнал A изменился с 1 на 0
28
if
(EncoderB) Result = eRight;
// B=1 => энкодер вращается по часовой
29
else
Result = eLeft;
// B=0 => энкодер вращается против часовой
30
}
31
EncoderAPrev = EncoderA;
// запомним текущее состояние
32
}
33
}
34
return
Result;
35
}
36
37
void
setup
() {
38
pinMode(pin_DT, INPUT);
39
pinMode(pin_CLK, INPUT);
40
pinMode(pin_Btn, INPUT_PULLUP);
// Кнопка не подтянута к +5 поэтому задействуем внутренний pull-up резистор
41
Serial
.begin(9600);
42
counter = 0;
43
}
44
45
void
loop
() {
46
47
if
(GetEncoderState() == eLeft)
Serial
.println(
"Left"
);
48
if
(GetEncoderState() == eRight)
Serial
.println(
"Right"
);
49
50
51
}
Здесь, на форуме, тема есть: "Работаем с энкодером", на последних страницах примеры работы от Dimax, на прерываниях. Попробуйте переделать, у меня после попыток запустить на библиотеках взлетело сразу. ИМХО.
transmit_data[7] - это восьмой элемент массива, а у вас объявлена размерность в семь элементов - int transmit_data[7]. Измените что-то одно, иначе словите баг с зависанием или порчей значений переменных и будете долго искать его.
Если имеется ввиду код от Dimax, приведенный ниже,я вставил нужные части в свой код, но он выдает только нули в мониторе порта. Порты энкодера поменять на свои я не забыл если что.
Код:
01
volatile
int
enc;
02
03
void
setup
() {
04
Serial
.begin(9600);
05
PCICR=1<<PCIE1;
//разрешить пренрывание
06
PCMSK1=(1<<PCINT19)|(1<<PCINT18);
//выбрать входы
07
}
08
09
10
ISR (PCINT1_vect){
11
static
byte
old_n=PINC&3;
// маска B00000011 что б читать только нужные 2 бита
12
byte
new_n=PINC&3;
13
if
(old_n==1&&new_n==3||old_n==2&&new_n==0) {enc++;}
14
if
(old_n==2&&new_n==3||old_n==1&&new_n==0) {enc--;}
15
old_n= new_n;
16
}
17
18
19
20
void
loop
() {
21
Serial
.println(enc);
22
}
"int transmit_data[7]"
А разве он не с 0 считает? 0, 1, ...., 7 итого 8 значений?
А теперь поменяй правильно. (везде, где надо менять)
Глядишь, и заработает.
Если имеется ввиду код от Dimax, приведенный ниже,я вставил нужные части в свой код, но он выдает только нули в мониторе порта. Порты энкодера поменять на свои я не забыл если что.
Я вот с этим работал. На 4 и 5 пинах, выдает две единицы на щелчок, с библиотекой глючило страшно. Пример из живого проекта:
01
long
oldEncPosition = -999;
02
long
curEncPosition = 0;
03
byte
DACSetStep = 1;
04
volatile
int
enc;
05
int
encoderValue = 0;
06
int
DACSetValue = 0;
07
08
//-----------------------------------------------------------------
09
10
void
getEncPosition()
11
{
12
curEncPosition = enc / 2;
13
14
if
(curEncPosition != oldEncPosition) {
15
if
(curEncPosition > oldEncPosition) {
16
encoderValue += DACSetStep;
17
18
if
(encoderValue > 4095) {
19
encoderValue = 4095;
20
}
21
}
else
{
22
encoderValue -= DACSetStep;
23
24
if
(encoderValue < 0) {
25
encoderValue = 0;
26
}
27
}
28
29
oldEncPosition = curEncPosition;
30
}
31
}
32
//-------------------------------------------------------------
33
34
//Обработка энкодера
35
ISR (PCINT2_vect) {
36
((PIND & 0x20) >> 4)^((PIND & 0x40) >> 5) ? enc++ : enc--;
37
}
38
//-------------------------------------------------------------
39
void
setup
() {
40
41
pinMode(5, INPUT_PULLUP);
//Пины энкодера и инициализация
42
pinMode(6, INPUT_PULLUP);
43
PCIFR = PCIFR;
44
PCICR = 1 << PCIE2;
//разрешить прерывание
45
PCMSK2 = 1 << PCINT21;
//выбрать вход на котором сработает прерывание
46
47
}
48
//----------------------------------------------------------------
49
50
void
loop
(
void
) {
51
//voltMeter();
52
//keyResult();
53
//dallRead(flagDallRead);
54
//lcdShow();
55
getEncPosition();
56
//temperatureExe();
57
58
}
59
//---------------------------------------------------------------
А теперь поменяй правильно. (везде, где надо менять)
Глядишь, и заработает.
Разве не только здесь??? Больше вроде там ни где нет выбора портов...
1
PCMSK1=(1<<PCINT18)|(1<<PCINT19);
//выбрать входы
bwn
Сначала в мониторе порта писал 1, но стоит повернуть энкодер в любую сторону, сразу 0 и как энкодер не крути все время 0.
Вот приведенный Вами код, который я использовал сейчас для теста:
01
long
oldEncPosition = -999;
02
long
curEncPosition = 0;
03
byte
DACSetStep = 1;
04
volatile
int
enc;
05
int
encoderValue = 0;
06
int
DACSetValue = 0;
07
08
//-----------------------------------------------------------------
09
10
void
getEncPosition()
11
{
12
curEncPosition = enc / 2;
13
14
if
(curEncPosition != oldEncPosition) {
15
if
(curEncPosition > oldEncPosition) {
16
encoderValue += DACSetStep;
17
18
if
(encoderValue > 4095) {
19
encoderValue = 4095;
20
}
21
}
else
{
22
encoderValue -= DACSetStep;
23
24
if
(encoderValue < 0) {
25
encoderValue = 0;
26
}
27
}
28
29
oldEncPosition = curEncPosition;
30
}
31
}
32
//-------------------------------------------------------------
33
34
//Обработка энкодера
35
ISR (PCINT2_vect) {
36
((PIND & 0x20) >> 4)^((PIND & 0x40) >> 5) ? enc++ : enc--;
37
}
38
//-------------------------------------------------------------
39
void
setup
() {
40
Serial
.begin(9600);
41
pinMode(2, INPUT_PULLUP);
//Пины энкодера и инициализация
42
pinMode(3, INPUT_PULLUP);
43
PCIFR = PCIFR;
44
PCICR = 1 << PCIE2;
//разрешить прерывание
45
PCMSK2 = 1 << PCINT19;
//выбрать вход на котором сработает прерывание
46
47
}
48
//----------------------------------------------------------------
49
50
void
loop
(
void
) {
51
//voltMeter();
52
//keyResult();
53
//dallRead(flagDallRead);
54
//lcdShow();
55
getEncPosition();
56
//temperatureExe();
57
Serial
.println(encoderValue);
58
}
bwn
Сначала в мониторе порта писал 1, но стоит повернуть энкодер в любую сторону, сразу 0 и как энкодер не крути все время 0.
>>4 & >>5 - ?????
>>4 & >>5 - ?????
[/quote]
Поменял я их, просто старую версию скинул, когда в самом IDE правил всё, то заметил, а вот в текстовом файле забыл поменять. Но всё равно результат 0 куда бы я не крутил энкодер и как бы я не менял местами порты (программно естевственно). Хотя в библиотеках всё работает нормально, а вот в моём коде не работает совсем.
Всё. Понял почему 0 все время, у меня энкодер походу сдох, если убрать if (encoderValue < 0) { encoderValue = 0; }, то в минус он крутиться! Щас попробую в свой код внести Ваш код, посмотрим что получится.
Разве не только здесь??? Больше вроде там ни где нет выбора портов...
1
PCMSK1=(1<<PCINT18)|(1<<PCINT19);
//выбрать входы
Конечно, нет.
Ты вообще понимаешь, что там написано? Если да, то ответь себе (мне не обязательно), какое отношение имеют к "PCINT18" и "PCINT19" в шестой строке к "PCIE1" в пятой?
Если надо, читай даташит пока не поймёшь, что там должно быть.
Скажу сразу, чтобы не было потом вопросов. Я не знаю что это за строчки (кроме тех где порты указаны так как там есть коммент //выбрать входы), могу только предположить, что они как-то связаны с управлением аппаратными функциями контроллера и не связаны с языком C, C# или CPP на котором пишут программы для Windows, Linux и даже MacOS. И как я уже писал ранее, я привык к Object Pascal (Delphi) и пишу на С так как писал бы на Delphi, так как изучал последний более 10 лет, C для меня сейчас слишком сложен в освоении, да и возраст уже не тот чтобы с нуля другой язык программирования изучать. Поэтому изпользую примеры и Google чтобы разбираться хотя бы в C, а про аппаратные коды контроллера я уже молчу, для меня они ещё более тёмный лес чем C, C# и CPP вместе взятые.
1
PCICR=1<<PCIE1;
2
PCMSK1=(1<<PCINT19)|(1<<PCINT18);
Откуда я знаю про то что порты это порты (PCINT18 - цифровой 2, PCINT19 - цифровой 3, куда у меня и подключен энкодер), так вот отсюда:
И кстати заработал код из этого сообщения, после того как я между вызовоми чтения с энкодера поставил задержку:
1
if
(GetEncoderState() == eRight){
2
lgt_sel++;
3
}
4
delay(60);
5
if
(GetEncoderState() == eLeft){
6
lgt_sel--;
7
}
Так тебе и дали пример. Ты его "поменял" и тут же заявил, что "пример от dimax не работает". Это пример от тебя не работает, а не от dimax, родной.
Я тебе задал вопрос
какое отношение имеют к "PCINT18" и "PCINT19" в шестой строке к "PCIE1" в пятой?
Неужели сама постановка вопроса не навела ни на какие мысли? Ладно, скажу проще, для "PCINT18" и "PCINT19" там нужно не "PCIE1", а что-то другое. Что именно? Ссылку на даташит я тебе дал, там это чёрным по белому написано - поработай хоть немного сам.
Я понял, что код из другого сообщения у тебя типа заработал, так что на этот ты можешь и забить (хотя он лучше и правильнее), но это уж тебе решать, ты хочешь научиться чему-то или взять чужой код и радоваться, что случайно заработало.
И так. Всё таки использовал я библиотеку GyverEncoder, только использовал в качестве основы пример под названием timer_isr, и теперь всё работает нормально.
Все файлы (включая библиотеки) можно скачать здесь, так же там есть фото того, ради чего я всё это разрабатывал.
И так. Всё таки использовал я библиотеку GyverEncoder..................
У каждого свой вкус, сказал Кот, вылизывая себе экстерьер.))))