Странные глюки с энкодером в моём коде + странности с nRF24L01+

nnm4evr
Offline
Зарегистрирован: 30.07.2017
Использую библиотеку (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-подобный язык мне сложно.
bwn
Offline
Зарегистрирован: 25.08.2014

Сперва выкиньте Гивера с его библиотекой, потом вставьте сюда код по нормальному, не многие хотят таскать к себе зипы х.з. откуда.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

nnm4evr пишет:

Использую библиотеку (GyverEncoder 3.1) ... проблема.

Не используйте и проблем не будет.

А если уж невмоготу, то за консультациями ходите не сюда, а на специализированный форум:  https://community.alexgyver.ru/

nnm4evr
Offline
Зарегистрирован: 30.07.2017

Ладно, фиг с ним с энкодером, может быть КОГДА-НИБУДЬ мне на форуме AlexGyver'а и ответят на этот вопрос.

Что не так с передачей/приёмом у nRF'ок? Привожу код ниже.

Код TX_response.ino:

#include <GyverEncoder.h>
#include <GyverButton.h>
#include <U8glib.h>
#include <SPI.h>
#include "Arduino.h"
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//                     BtmpName Width x Height
#include "bat_lt.h" // BatLT 13 x 6
#include "bat_rc.h" // BatRC 13 x 6
#include "lt_big.h" // LtBig 12 x 11
#include "lt_big_on.h" // LtBigOn 10 x 9
#include "lt_big_sel.h" // LtBigSel 16 x 15
#include "lt_matt.h" // LtMatt 9 x 21
#include "lt_matt_on.h" // LtMattOn 7 x 7
#include "lt_matt_ref_sel.h" // LtMattRefSel 15 x 25
#include "lt_ref.h" // LtRef 9 x 21
#include "lt_ref_on.h" // LtRefOn 7 x 7
#include "sym_lt.h" // SymLT 10 x 6
#include "sym_rc.h" // SymRC 9 x 6

#define CH_NUM 0x70 
#define SIG_POWER RF24_PA_HIGH
#define SIG_SPEED RF24_1MBPS

U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
GButton butt1(5);
GButton butt2(6);
Encoder enc1(3, 2, 4);
RF24 radio(9, 10);

byte address[][10] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node", "7Node", "8Node", "9Node", "10Node"};
byte rssi;
byte latest_data[6];

//float my_vcc_const = ;

#define vol_calibration 0    // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
float my_vcc_const = 1.1;    // начальное значение константы должно быть 1.1
#include "EEPROMex.h"

char mode[4]={0}, bright[4]={0};

boolean sleep = false, flag, select, sel_clk;

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;
int transmit_data[6];  
int recieved_data[1]; 
int trnsmtd_pack = 1, failed_pack;

unsigned long RSSI_timer, currentTime, loopTime;

void splash_screen(void) {
  u8g.setFont(u8g_font_7x14B);
  u8g.drawStr( 32, 26, "Loading...");
}

void light_is_off(void) {
  u8g.setFont(u8g_font_7x14B);
  u8g.drawStr( 3, 26, "Main Light is Off!");
}

void draw(void) {
u8g.drawXBMP( 0, 0, 13, 6, BatLT);
u8g.drawXBMP( 115, 0, 13, 6, BatRC);
u8g.drawXBMP( 17, 0, 10, 6, SymLT);
u8g.drawXBMP( 102, 0, 9, 6, SymRC);
u8g.drawXBMP( 40, 9, 9, 21, LtMatt);
u8g.drawXBMP( 79, 9, 9, 21, LtRef);
u8g.drawXBMP( 58, 2, 12, 11, LtBig);
u8g.setFont(u8g_font_7x14B);
u8g.drawStr( 1, 31, "x");
u8g.setFont(u8g_font_9x15B);
u8g.drawStr( 12, 31, mode);
u8g.drawStr( 100, 31, bright);
if (sel_clk == true) u8g.drawStr( 60, 31, "%");
if (lgt_sel == 1) u8g.drawXBMP( 37, 7, 15, 25, LtMattRefSel);
if (lgt_sel == 2) u8g.drawXBMP( 56, 0, 16, 15, LtBigSel);
if (lgt_sel == 3) u8g.drawXBMP( 76, 7, 15, 25, LtMattRefSel);
if (lgt_matt == 1) {
  u8g.drawXBMP( 41, 10, 7, 7, LtMattOn);
  u8g.drawXBMP( 41, 22, 7, 7, LtMattOn);
}
if (lgt_big == 1) u8g.drawXBMP( 59, 3, 10, 9, LtBigOn);
if (lgt_ref == 1) {
  u8g.drawXBMP( 80, 10, 7, 7, LtRefOn);
  u8g.drawXBMP( 80, 22, 7, 7, LtRefOn);
}

// LT Batt Lines  
if (lgt_batt > 5) {u8g.drawLine(1, 1, 1, 5);} // 1-10
if (lgt_batt > 10) {u8g.drawLine(2, 1, 2, 5);} // 10-20
if (lgt_batt > 20) {u8g.drawLine(3, 1, 3, 5);} // 20-30
if (lgt_batt > 30) {u8g.drawLine(4, 1, 4, 5);} // 30-40
if (lgt_batt > 40) {u8g.drawLine(5, 1, 5, 5);} // 40-50
if (lgt_batt > 50) {u8g.drawLine(6, 1, 6, 5);} // 50-60
if (lgt_batt > 60) {u8g.drawLine(7, 1, 7, 5);} // 60-70
if (lgt_batt > 70) {u8g.drawLine(8, 1, 8, 5);} // 70-80
if (lgt_batt > 80) {u8g.drawLine(9, 1, 9, 5);} // 80-90
if (lgt_batt > 90) {u8g.drawLine(10, 1, 10, 5);} // 90-100
// RC Batt Lines
if (rc_batt > 5) {u8g.drawLine(126, 1, 126, 5);} // 1-10
if (rc_batt > 10) {u8g.drawLine(125, 1, 125, 5);} // 10-20
if (rc_batt > 20) {u8g.drawLine(124, 1, 124, 5);} // 20-30
if (rc_batt > 30) {u8g.drawLine(123, 1, 123, 5);} // 30-40
if (rc_batt > 40) {u8g.drawLine(122, 1, 122, 5);} // 40-50
if (rc_batt > 50) {u8g.drawLine(121, 1, 121, 5);} // 50-60
if (rc_batt > 60) {u8g.drawLine(120, 1, 120, 5);} // 60-70
if (rc_batt > 70) {u8g.drawLine(119, 1, 119, 5);} // 70-80
if (rc_batt > 80) {u8g.drawLine(118, 1, 118, 5);} // 80-90
if (rc_batt > 90) {u8g.drawLine(117, 1, 117, 5);} // 90-100
}

void setup() {
  Serial.begin(9600);
  radioSetup();
  delay(300);
  butt1.setDebounce(90); 
  butt1.setTimeout(500);  
  butt1.setType(HIGH_PULL);
  butt1.setDirection(NORM_OPEN);
  butt1.setTickMode(AUTO);
  butt2.setDebounce(90);   
  butt2.setTimeout(500);  
  butt2.setType(HIGH_PULL);
  butt2.setDirection(NORM_OPEN);
  butt2.setTickMode(AUTO);
//  enc1.setType(TYPE1);
  enc1.setTickMode(AUTO);
  select = false;
  bright_var = 100;
  bright_mode = 10;
  lgt_sel = 0;
  lgt_ref = 0;
  lgt_big = 0;
  lgt_matt = 0;
  lgt_ref_br = 100;
  lgt_big_br = 100;
  lgt_matt_br = 100;  
  sel_clk = false;
  currentTime = millis();
  loopTime = currentTime;
if (vol_calibration) calibration();     // калибровка, если разрешена
my_vcc_const = EEPROM.readFloat(1000);  // считать константу из памяти
}

void loop() {
currentTime = millis();

//Serial.println(currentTime);

if (currentTime >= (loopTime + 180000)) {
  sleep = true;
}

if (sleep == true) {
  u8g.sleepOn();
  radio.powerDown();
if (butt1.isClick() || butt2.isClick() || enc1.isRight() || enc1.isLeft() || enc1.isPress()){
  sleep = false;
  loopTime = currentTime;
  radio.powerUp();
}
}

if (sleep == false) {
u8g.sleepOff();
 
if (currentTime < 5000) {  
transmit_data[0] = 1; 
  if (radio.write(&transmit_data, sizeof(transmit_data))) {  
    trnsmtd_pack++;
    if (!radio.available()) { 
    } else {
      while (radio.available() ) {  
        radio.read(&recieved_data, sizeof(recieved_data));	
		lgt_on = recieved_data[0];
      }
    }
  } else {
    failed_pack++;
  } 
 
   u8g.firstPage();  
 do {
    splash_screen();     
  } while( u8g.nextPage() ); 
 
}

if (currentTime > 5500 && lgt_on == 0) {
    u8g.firstPage();  
  do {
    light_is_off();
  } while( u8g.nextPage() );
delay(4000);
}

if (currentTime > 5500 && lgt_on == 1) {

lgt_on = 1;

V = analogRead(A0) * (readVcc() / 1023.0);
rc_batt = map(V, 2900, 4250, 0, 100);

if (select == false){ 
if (enc1.isHolded()){ 
  select = true;
  lgt_sel = 1;
  Serial.println("Selection Mode ON");
  Serial.println(lgt_sel);
}
}

if (select == true){

if (butt2.isClick()) {
if (sel_clk == false){
  sel_clk = true;
  Serial.println("Selection Click Enable");
} else {
  sel_clk = false;
  Serial.println("Selection Click Disable");
}
}

if (sel_clk == false){
  if (enc1.isTurn()) {
Serial.println("Encoder Turn...");
  }
  
if (enc1.isRight()){ lgt_sel++;
Serial.println("Right");
Serial.println(lgt_sel);
}
if (enc1.isLeft()){ lgt_sel--;
Serial.println("Left");
Serial.println(lgt_sel);
}
if (lgt_sel > 3) lgt_sel = 1;
if (lgt_sel < 1) lgt_sel = 3;
if (enc1.isHolded()) {
  select = false;
  lgt_sel = 0;
  Serial.println("Selection Mode OFF");
  Serial.println(lgt_sel);
}
}
}

if (sel_clk == true){
if (lgt_sel == 1) {
  bright_var = lgt_matt_br;
if (bright_mode == 1) {
  if (butt2.isHolded()) bright_mode = 10;
  if (enc1.isRight()) bright_var = bright_var + 1;
  if (enc1.isLeft()) bright_var = bright_var - 1;
  bright_var = constrain(bright_var, 0, 100);
  lgt_matt_br = bright_var;
} else {
  if (butt2.isHolded()) bright_mode = 1;
  if (enc1.isRight()) bright_var = bright_var + 10;
  if (enc1.isLeft()) bright_var = bright_var - 10;
  bright_var = constrain(bright_var, 0, 100);
  lgt_matt_br = bright_var;
}
if (lgt_matt == 0) {
  if (butt1.isClick()) lgt_matt = 1;
} else {
  if (butt1.isClick()) lgt_matt = 0;
}
}

if (lgt_sel == 2) {
  bright_var = lgt_big_br;
 if (bright_mode == 1) {
  if (butt2.isHolded()) bright_mode = 10;
  if (enc1.isRight()) bright_var = bright_var + 1;
  if (enc1.isLeft()) bright_var = bright_var - 1;
  bright_var = constrain(bright_var, 0, 100);
  lgt_big_br = bright_var;
} else {
  if (butt2.isHolded()) bright_mode = 1;
  if (enc1.isRight()) bright_var = bright_var + 10;
  if (enc1.isLeft()) bright_var = bright_var - 10;
  bright_var = constrain(bright_var, 0, 100);
  lgt_big_br = bright_var;
}
if (lgt_big == 0) {
  if (butt1.isClick()) lgt_big = 1;
} else {
  if (butt1.isClick()) lgt_big = 0;
} 
}

if (lgt_sel == 3) {
  bright_var = lgt_ref_br;
  if (bright_mode == 1) {
  if (butt2.isHolded()) bright_mode = 10;
  if (enc1.isRight()) bright_var = bright_var + 1;
  if (enc1.isLeft()) bright_var = bright_var - 1;
  bright_var = constrain(bright_var, 0, 100);
  lgt_ref_br = bright_var;
} else {
  if (butt2.isHolded()) bright_mode = 1;
  if (enc1.isRight()) bright_var = bright_var + 10;
  if (enc1.isLeft()) bright_var = bright_var - 10;
  bright_var = constrain(bright_var, 0, 100);
  lgt_ref_br = bright_var;
}
if (lgt_ref == 0) {
  if (butt1.isClick()) lgt_ref = 1;
} else {
  if (butt1.isClick()) lgt_ref = 0;
}
}
}

sprintf(mode, "%02d", bright_mode);
sprintf(bright, "%03d", bright_var);

transmit_data[0] = 1;
transmit_data[1] = lgt_ref;
transmit_data[2] = lgt_big;
transmit_data[3] = lgt_matt;
transmit_data[4] = lgt_ref_br;
transmit_data[5] = lgt_big_br;
transmit_data[6] = lgt_matt_br;
 
Serial.println(lgt_matt_br);

  if (radio.write(&transmit_data, sizeof(transmit_data))) { 
    trnsmtd_pack++;
    if (!radio.available()) { 
    } else {
      while (radio.available() ) { 
        radio.read(&recieved_data, sizeof(recieved_data));
		lgt_batt = recieved_data[1];
    Serial.println(lgt_batt);
      }
    }
  } else {
    failed_pack++;
  }


    u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() ); 

 


  if (millis() - RSSI_timer > 1000) { 
    
    rssi = (1 - ((float)failed_pack / trnsmtd_pack)) * 100;

    failed_pack = 0;
    trnsmtd_pack = 0;
    RSSI_timer = millis();
  }
}
}
}


void radioSetup() {
  radio.begin();  
  radio.setAutoAck(1);  
  radio.setRetries(0, 15); 
  radio.enableAckPayload(); 
  radio.setPayloadSize(32); 
  radio.openWritingPipe(address[0]); 
  radio.setChannel(CH_NUM);
  radio.setPALevel(SIG_POWER); 
  radio.setDataRate(SIG_SPEED); 
  radio.powerUp(); 
  radio.stopListening(); 
}

void calibration() {
my_vcc_const = 1.1;                                           // начальаня константа калибровки
Serial.print("Real VCC is: "); Serial.println(readVcc());     // общаемся с пользователем
Serial.println("Write your VCC (in millivolts)");
while (Serial.available() == 0); int Vcc = Serial.parseInt(); // напряжение от пользователя
float real_const = (float)1.1 * Vcc / readVcc();              // расчёт константы
Serial.print("New voltage constant: "); Serial.println(real_const, 3);
Serial.println("Set vol_calibration 0, flash and enjoy!");
EEPROM.writeFloat(1000, real_const);                          // запись в EEPROM
while (1);                                                    // уйти в бесконечный цикл
}

long readVcc() {
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2);
  ADCSRA |= _BV(ADSC); 
  while (bit_is_set(ADCSRA, ADSC)); 
  uint8_t low  = ADCL; 
  uint8_t high = ADCH;
  long result = (high << 8) | low;
  result = my_vcc_const * 1023 * 1000 / result; 
  return result; 
}

Код RX_response.ino:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

#define CH_NUM 0x70
#define SIG_POWER RF24_PA_MIN
#define SIG_SPEED RF24_1MBPS

RF24 radio(9, 10); 

byte pipeNo;
byte address[][10] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node", "7Node", "8Node", "9Node", "10Node"};

int recieved_data[6];  
int transmit_data[1]; 

int V, Bat;

#define vol_calibration 0    // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
float my_vcc_const = 1.1;    // начальное значение константы должно быть 1.1
#include "EEPROMex.h"

void setup() {
  Serial.begin(9600);
  radioSetup();
  delay(300);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  analogWrite(3, 0);
  analogWrite(5, 0);
  analogWrite(6, 0);
  digitalWrite(7, LOW);
  if (vol_calibration) calibration();     // калибровка, если разрешена
my_vcc_const = EEPROM.readFloat(1000);  // считать константу из памяти
}

void loop() {
V = analogRead(A0) * (readVcc() / 1023.0);
Bat = map(V, 2900, 4250, 0, 100);

  while (radio.available(&pipeNo)) { 
    radio.read( &recieved_data, sizeof(recieved_data));

transmit_data[0] = 1;
transmit_data[1] = Bat;

    radio.writeAckPayload(pipeNo, &transmit_data, sizeof(transmit_data));
    Serial.println(Bat);
  }
 
if (recieved_data[1] == 1) {
  analogWrite(3, map(recieved_data[4], 0, 100, 0, 255));
//  Serial.println("LAMP 1");
  Serial.println(recieved_data[4]);
} else {
  analogWrite(3, 0);
//  Serial.println("LAMP 1 OFF");
}

if (recieved_data[2] == 1) {
  digitalWrite(7, HIGH);
  analogWrite(5, map(recieved_data[5], 0, 100, 0, 255));
//  Serial.println("LAMP 2");
  Serial.println(recieved_data[5]);
} else {
  digitalWrite(7, LOW);
  analogWrite(5, 0);
//  Serial.println("LAMP 2 OFF");
}

if (recieved_data[3] == 1) {
  analogWrite(6, map(recieved_data[6], 0, 100, 0, 255));
  Serial.println("LAMP 3");
  Serial.println(recieved_data[6]);
  Serial.println(recieved_data[3]);
} else {
  analogWrite(6, 0);
  Serial.println("LAMP 3 OFF");
} 
  
}

void radioSetup() { 
  radio.begin(); 
  radio.setAutoAck(1); 
  radio.setRetries(0, 15);
  radio.enableAckPayload();
  radio.setPayloadSize(32); 
  radio.openReadingPipe(1, address[0]);
  radio.setChannel(CH_NUM); 
  radio.setPALevel(SIG_POWER);
  radio.setDataRate(SIG_SPEED); 
  radio.powerUp();  
  radio.startListening(); 
}

void calibration() {
my_vcc_const = 1.1;                                           // начальаня константа калибровки
Serial.print("Real VCC is: "); Serial.println(readVcc());     // общаемся с пользователем
Serial.println("Write your VCC (in millivolts)");
while (Serial.available() == 0); int Vcc = Serial.parseInt(); // напряжение от пользователя
float real_const = (float)1.1 * Vcc / readVcc();              // расчёт константы
Serial.print("New voltage constant: "); Serial.println(real_const, 3);
Serial.println("Set vol_calibration 0, flash and enjoy!");
EEPROM.writeFloat(1000, real_const);                          // запись в EEPROM
while (1);                                                    // уйти в бесконечный цикл
}

long readVcc() {
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2);
  ADCSRA |= _BV(ADSC); 
  while (bit_is_set(ADCSRA, ADSC)); 
  uint8_t low  = ADCL; 
  uint8_t high = ADCH;
  long result = (high << 8) | low;
  result = my_vcc_const * 1023 * 1000 / result; 
  return result; 
}

 

b707
Offline
Зарегистрирован: 26.05.2017

nmm4evr - если у вас проблемы с передачей - самое правильное отладить прием-передачу отдельно от остального. Почистите код от всего лишнего. Код приемника и код передатчика NRF - это максимум 20 строк каждый, а не по 400 строк, не имющих ровно никакого отношения к радио

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nnm4evr пишет:

Что не так с передачей/приёмом у nRF'ок? Привожу код ниже.

Парень, ты только здесь так тупишь, или по жизни альтернативно одарённый?

Поясняю, медленно и громко: Вероятность того, что здесь кто-то прочитает код, начинающийся с

#include <Gyver...

дальше первой строки, практически неотличима от нуля.

Так понятно?

Тебе уже сказали, куда с этим кодом обратиться. Так зачем добиваться, чтобы в другие места посылать начали?

nnm4evr
Offline
Зарегистрирован: 30.07.2017

Вот! Убрал ВСЁ что не связано с nRF. Библиотеки AlexGyver'а к nRF ВООБЩЕ ни какого отношения не имеют, я их использовал только для кнопки и энкодера. ТАК ЛУЧШЕ?! И чем Вам AlexGyver не угодил? Удобные же у него библиотеки, не нужно писать километр кода (в котором я не слишком хорошо разбираюсь) в обвязку к кнопке или энкодеру чтобы всё работало нормально Б........

Вот очищеный код, который работает криво, а именно как, описано в первом посте темы.

#include <U8glib.h>
#include <SPI.h>
#include "Arduino.h"
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//                     BtmpName Width x Height
#include "bat_lt.h" // BatLT 13 x 6
#include "bat_rc.h" // BatRC 13 x 6
#include "lt_big.h" // LtBig 12 x 11
#include "lt_big_on.h" // LtBigOn 10 x 9
#include "lt_big_sel.h" // LtBigSel 16 x 15
#include "lt_matt.h" // LtMatt 9 x 21
#include "lt_matt_on.h" // LtMattOn 7 x 7
#include "lt_matt_ref_sel.h" // LtMattRefSel 15 x 25
#include "lt_ref.h" // LtRef 9 x 21
#include "lt_ref_on.h" // LtRefOn 7 x 7
#include "sym_lt.h" // SymLT 10 x 6
#include "sym_rc.h" // SymRC 9 x 6

#define CH_NUM 0x70 
#define SIG_POWER RF24_PA_HIGH
#define SIG_SPEED RF24_1MBPS

U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
RF24 radio(9, 10);

byte address[][10] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node", "7Node", "8Node", "9Node", "10Node"};
byte rssi;
byte latest_data[6];

//float my_vcc_const = ;

#define vol_calibration 0    // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
float my_vcc_const = 1.1;    // начальное значение константы должно быть 1.1
#include "EEPROMex.h"

char mode[4]={0}, bright[4]={0};

boolean sleep = false, flag, select, sel_clk;

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;
int transmit_data[6];  
int recieved_data[1]; 
int trnsmtd_pack = 1, failed_pack;

unsigned long RSSI_timer, currentTime, loopTime;

void splash_screen(void) {
  u8g.setFont(u8g_font_7x14B);
  u8g.drawStr( 32, 26, "Loading...");
}

void light_is_off(void) {
  u8g.setFont(u8g_font_7x14B);
  u8g.drawStr( 3, 26, "Main Light is Off!");
}

void draw(void) {
u8g.drawXBMP( 0, 0, 13, 6, BatLT);
u8g.drawXBMP( 115, 0, 13, 6, BatRC);
u8g.drawXBMP( 17, 0, 10, 6, SymLT);
u8g.drawXBMP( 102, 0, 9, 6, SymRC);
u8g.drawXBMP( 40, 9, 9, 21, LtMatt);
u8g.drawXBMP( 79, 9, 9, 21, LtRef);
u8g.drawXBMP( 58, 2, 12, 11, LtBig);
u8g.setFont(u8g_font_7x14B);
u8g.drawStr( 1, 31, "x");
u8g.setFont(u8g_font_9x15B);
u8g.drawStr( 12, 31, mode);
u8g.drawStr( 100, 31, bright);
if (sel_clk == true) u8g.drawStr( 60, 31, "%");
if (lgt_sel == 1) u8g.drawXBMP( 37, 7, 15, 25, LtMattRefSel);
if (lgt_sel == 2) u8g.drawXBMP( 56, 0, 16, 15, LtBigSel);
if (lgt_sel == 3) u8g.drawXBMP( 76, 7, 15, 25, LtMattRefSel);
if (lgt_matt == 1) {
  u8g.drawXBMP( 41, 10, 7, 7, LtMattOn);
  u8g.drawXBMP( 41, 22, 7, 7, LtMattOn);
}
if (lgt_big == 1) u8g.drawXBMP( 59, 3, 10, 9, LtBigOn);
if (lgt_ref == 1) {
  u8g.drawXBMP( 80, 10, 7, 7, LtRefOn);
  u8g.drawXBMP( 80, 22, 7, 7, LtRefOn);
}

// LT Batt Lines  
if (lgt_batt > 5) {u8g.drawLine(1, 1, 1, 5);} // 1-10
if (lgt_batt > 10) {u8g.drawLine(2, 1, 2, 5);} // 10-20
if (lgt_batt > 20) {u8g.drawLine(3, 1, 3, 5);} // 20-30
if (lgt_batt > 30) {u8g.drawLine(4, 1, 4, 5);} // 30-40
if (lgt_batt > 40) {u8g.drawLine(5, 1, 5, 5);} // 40-50
if (lgt_batt > 50) {u8g.drawLine(6, 1, 6, 5);} // 50-60
if (lgt_batt > 60) {u8g.drawLine(7, 1, 7, 5);} // 60-70
if (lgt_batt > 70) {u8g.drawLine(8, 1, 8, 5);} // 70-80
if (lgt_batt > 80) {u8g.drawLine(9, 1, 9, 5);} // 80-90
if (lgt_batt > 90) {u8g.drawLine(10, 1, 10, 5);} // 90-100
// RC Batt Lines
if (rc_batt > 5) {u8g.drawLine(126, 1, 126, 5);} // 1-10
if (rc_batt > 10) {u8g.drawLine(125, 1, 125, 5);} // 10-20
if (rc_batt > 20) {u8g.drawLine(124, 1, 124, 5);} // 20-30
if (rc_batt > 30) {u8g.drawLine(123, 1, 123, 5);} // 30-40
if (rc_batt > 40) {u8g.drawLine(122, 1, 122, 5);} // 40-50
if (rc_batt > 50) {u8g.drawLine(121, 1, 121, 5);} // 50-60
if (rc_batt > 60) {u8g.drawLine(120, 1, 120, 5);} // 60-70
if (rc_batt > 70) {u8g.drawLine(119, 1, 119, 5);} // 70-80
if (rc_batt > 80) {u8g.drawLine(118, 1, 118, 5);} // 80-90
if (rc_batt > 90) {u8g.drawLine(117, 1, 117, 5);} // 90-100
}

void setup() {
  Serial.begin(9600);
  radioSetup();
  delay(300);
  select = false;
  bright_var = 100;
  bright_mode = 10;
  lgt_sel = 0;
  lgt_ref = 0;
  lgt_big = 0;
  lgt_matt = 0;
  lgt_ref_br = 100;
  lgt_big_br = 100;
  lgt_matt_br = 100;  
  sel_clk = false;
  currentTime = millis();
  loopTime = currentTime;
if (vol_calibration) calibration();     // калибровка, если разрешена
my_vcc_const = EEPROM.readFloat(1000);  // считать константу из памяти
}

void loop() {
currentTime = millis();

//Serial.println(currentTime);

if (currentTime >= (loopTime + 180000)) {
  sleep = true;
}

if (sleep == true) {
  u8g.sleepOn();
  radio.powerDown();
if (Нажатие кнопки или поворот энкодера){
  sleep = false;
  loopTime = currentTime;
  radio.powerUp();
}
}

if (sleep == false) {
u8g.sleepOff();
 
if (currentTime < 5000) {  
transmit_data[0] = 1; 
  if (radio.write(&transmit_data, sizeof(transmit_data))) {  
    trnsmtd_pack++;
    if (!radio.available()) { 
    } else {
      while (radio.available() ) {  
        radio.read(&recieved_data, sizeof(recieved_data));	
		lgt_on = recieved_data[0];
      }
    }
  } else {
    failed_pack++;
  } 
 
   u8g.firstPage();  
 do {
    splash_screen();     
  } while( u8g.nextPage() ); 
 
}

if (currentTime > 5500 && lgt_on == 0) {
    u8g.firstPage();  
  do {
    light_is_off();
  } while( u8g.nextPage() );
delay(4000);
}

if (currentTime > 5500 && lgt_on == 1) {

lgt_on = 1;

V = analogRead(A0) * (readVcc() / 1023.0);
rc_batt = map(V, 2900, 4250, 0, 100);


sprintf(mode, "%02d", bright_mode);
sprintf(bright, "%03d", bright_var);

transmit_data[0] = 1;
transmit_data[1] = lgt_ref;
transmit_data[2] = lgt_big;
transmit_data[3] = lgt_matt;
transmit_data[4] = lgt_ref_br;
transmit_data[5] = lgt_big_br;
transmit_data[6] = lgt_matt_br;
 
Serial.println(lgt_matt_br);

  if (radio.write(&transmit_data, sizeof(transmit_data))) { 
    trnsmtd_pack++;
    if (!radio.available()) { 
    } else {
      while (radio.available() ) { 
        radio.read(&recieved_data, sizeof(recieved_data));
		lgt_batt = recieved_data[1];
    Serial.println(lgt_batt);
      }
    }
  } else {
    failed_pack++;
  }


    u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() ); 

 


  if (millis() - RSSI_timer > 1000) { 
    
    rssi = (1 - ((float)failed_pack / trnsmtd_pack)) * 100;

    failed_pack = 0;
    trnsmtd_pack = 0;
    RSSI_timer = millis();
  }
}
}
}


void radioSetup() {
  radio.begin();  
  radio.setAutoAck(1);  
  radio.setRetries(0, 15); 
  radio.enableAckPayload(); 
  radio.setPayloadSize(32); 
  radio.openWritingPipe(address[0]); 
  radio.setChannel(CH_NUM);
  radio.setPALevel(SIG_POWER); 
  radio.setDataRate(SIG_SPEED); 
  radio.powerUp(); 
  radio.stopListening(); 
}

void calibration() {
my_vcc_const = 1.1;                                          
Serial.print("Real VCC is: "); Serial.println(readVcc());  
Serial.println("Write your VCC (in millivolts)");
while (Serial.available() == 0); int Vcc = Serial.parseInt(); 
float real_const = (float)1.1 * Vcc / readVcc();             
Serial.print("New voltage constant: "); Serial.println(real_const, 3);
Serial.println("Set vol_calibration 0, flash and enjoy!");
EEPROM.writeFloat(1000, real_const);                         
while (1);                                                  
}

long readVcc() {
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2);
  ADCSRA |= _BV(ADSC); 
  while (bit_is_set(ADCSRA, ADSC)); 
  uint8_t low  = ADCL; 
  uint8_t high = ADCH;
  long result = (high << 8) | low;
  result = my_vcc_const * 1023 * 1000 / result; 
  return result; 
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

nnm4evr пишет:

И чем Вам AlexGyver не угодил? Удобные же у него библиотеки, не нужно писать километр кода (в котором я не слишком хорошо разбираюсь) в обвязку к кнопке или энкодеру чтобы всё работало нормально Б........

Они может и удобные, только сильно глючные, а приводить их в порядок он не собирается.

b707
Offline
Зарегистрирован: 26.05.2017

nnm4evr пишет:

Вот! Убрал ВСЁ что не связано с nRF.

 

Вранье!

из оставшихся 250 (или сколько там) строк - 200 это вывод на экран известной своими заморочками либы U8glib, которая легко может имитировать неработоспособность NRF

вы плохо понимаете? - 20 строк оставьте! а не 200

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nnm4evr пишет:
чем Вам AlexGyver не угодил? Удобные же у него библиотеки, не нужно писать километр кода (в котором я не слишком хорошо разбираюсь) в обвязку к кнопке или энкодеру чтобы всё работало нормально

А кто тебе сказал, что с его библиотеками всё работает нормально? Вот у тебя не работает, и таких как ты тут знаешь сколько ходит? Вот, и на других форумах пострадавшие имеются.

 Я лично не видел ни одной его библиотеки, в которой не было бы откровенных ляпов. Ни одной! 

Он тут как-то выложил кучу своих библиотек. Ему показали явные и скрытые ошибки. Например: #3#26#29#31#52#67.

А вот теперь, полезь и посмотри, сколько из них он поправил, а сколько так и остались ляпами.

nnm4evr
Offline
Зарегистрирован: 30.07.2017
[Ворота]
 
Пока что из всех его библиотек я использовал только GyverButton и GyverEncoder, не спорю, с последней есть глюки, но GyverButton я использовал уже в 4х своих проектах и глюков пока не наблюдал.
 
[bwn]
 
Код в ардуино отрабатывается по строчно? Одна строка за другой? Если да, то каким образом библиотека для передачи изображения на дисплей может влиять на библиотеку для передачи данных через nRF'ки? Причем только на пару переменных, и то на одну отправляемую и на другую принимаемую? Прикрепляю картинку как я вижу происходящее, вначале ортабатывается код с цифрой "1", а уже потом идет код отрисовки на дисплей под цифрой "2".
mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

nnm4evr пишет:

Код в ардуино отрабатывается по строчно?

Нет

nnm4evr пишет:

Одна строка за другой?

Тоже нет

Вы сами признались, что в программировании не очень, но упорно спорите с людьми, знающими о нем на порядок или даже на пару больше

b707
Offline
Зарегистрирован: 26.05.2017

nnm4evr пишет:

каким образом библиотека для передачи изображения на дисплей может влиять на библиотеку для передачи данных через nRF'ки?

В условиях ограниченности ресурсов - а для программирования МК это норма - легко может влиять. Нехватка памяти, работа двух библиотек с одним и тем же таймеров, конфликт прерываний, некорректное обращение к периферии...

Ваша задача при отладке - максимально отделить влияние одной библиотеки от другой. Впрочем, если вы уверены, что знаете более простой и легкий путь найти ошибки - ищите сами.

nnm4evr
Offline
Зарегистрирован: 30.07.2017

Избавился от библиотек от AlexGyver.

С nRF24L01+ более-менее разобрался просто добавив в массив ещё одно значение и записав туда ноль, может оно и считывается/передается с глюками, но зато все остальные значения массива теперь передаются нормально и то хорошо.

Но вот с энкодером все равно ни чего не получается, ну вот не работает он и ВСЁ тут, кнопки работают и кнопка энкодера тоже, я уже даже конденсаторы на 100 нФ припаял чтобы дребезги на энкодере убрать, вот в примере того что я щас использую вместо GyverEncoder всё работает, в моём коде не работает ни в какую.

Прикладываю код примера и код TX_response.

TX_response:

#include <U8glib.h>
#include <SPI.h>
#include "Arduino.h"
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include "sav_button.h"
//                     BtmpName Width x Height
#include "bat_lt.h" // BatLT 13 x 6
#include "bat_rc.h" // BatRC 13 x 6
#include "lt_big.h" // LtBig 12 x 11
#include "lt_big_on.h" // LtBigOn 10 x 9
#include "lt_big_sel.h" // LtBigSel 16 x 15
#include "lt_matt.h" // LtMatt 9 x 21
#include "lt_matt_on.h" // LtMattOn 7 x 7
#include "lt_matt_ref_sel.h" // LtMattRefSel 15 x 25
#include "lt_ref.h" // LtRef 9 x 21
#include "lt_ref_on.h" // LtRefOn 7 x 7
#include "sym_lt.h" // SymLT 10 x 6
#include "sym_rc.h" // SymRC 9 x 6

#define CH_NUM 0x70 
#define SIG_POWER RF24_PA_HIGH
#define SIG_SPEED RF24_1MBPS
#define pin_CLK 2
#define pin_DT  3
#define pin_Btn 7

SButton button1(4,50,2000,0,1000);
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
RF24 radio(9, 10);

byte address[][10] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node", "7Node", "8Node", "9Node", "10Node"};
//byte rssi;
byte latest_data[6];

#define vol_calibration 0    // калибровка вольтметра (если работа от АКБ) 1 - включить, 0 - выключить
float my_vcc_const = 1.1;    // начальное значение константы должно быть 1.1
#include "EEPROMex.h"

char mode[4]={0}, bright[4]={0};

boolean sleep = false, flag, select, sel_clk, ButtonPrev;

const int butt1Pin = 5;
const int butt2Pin = 6;

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;
int transmit_data[7];  
int recieved_data[2]; 
int EncoderA, EncoderB, EncoderAPrev, butt1 = 0, butt2 = 0;
//int trnsmtd_pack = 1, failed_pack;

unsigned long RSSI_timer, currentTime, loopTime, CurrTime, LastTime;

enum eEncoderState {eNone, eLeft, eRight, eButton};

void splash_screen(void) {
  u8g.setFont(u8g_font_7x14B);
  u8g.drawStr( 32, 26, "Loading...");
}

void light_is_off(void) {
  u8g.setFont(u8g_font_7x14B);
  u8g.drawStr( 3, 26, "Main Light is Off!");
}

void draw(void) {
u8g.drawXBMP( 0, 0, 13, 6, BatLT);
u8g.drawXBMP( 115, 0, 13, 6, BatRC);
u8g.drawXBMP( 17, 0, 10, 6, SymLT);
u8g.drawXBMP( 102, 0, 9, 6, SymRC);
u8g.drawXBMP( 40, 9, 9, 21, LtMatt);
u8g.drawXBMP( 79, 9, 9, 21, LtRef);
u8g.drawXBMP( 58, 2, 12, 11, LtBig);
u8g.setFont(u8g_font_7x14B);
u8g.drawStr( 1, 31, "x");
u8g.setFont(u8g_font_9x15B);
u8g.drawStr( 12, 31, mode);
u8g.drawStr( 100, 31, bright);
if (sel_clk == true) u8g.drawStr( 60, 31, "%");
if (lgt_sel == 1) u8g.drawXBMP( 37, 7, 15, 25, LtMattRefSel);
if (lgt_sel == 2) u8g.drawXBMP( 56, 0, 16, 15, LtBigSel);
if (lgt_sel == 3) u8g.drawXBMP( 76, 7, 15, 25, LtMattRefSel);
if (lgt_matt == 1) {
  u8g.drawXBMP( 41, 10, 7, 7, LtMattOn);
  u8g.drawXBMP( 41, 22, 7, 7, LtMattOn);
}
if (lgt_big == 1) u8g.drawXBMP( 59, 3, 10, 9, LtBigOn);
if (lgt_ref == 1) {
  u8g.drawXBMP( 80, 10, 7, 7, LtRefOn);
  u8g.drawXBMP( 80, 22, 7, 7, LtRefOn);
}

// LT Batt Lines  
if (lgt_batt > 5) {u8g.drawLine(1, 1, 1, 5);} // 1-10
if (lgt_batt > 10) {u8g.drawLine(2, 1, 2, 5);} // 10-20
if (lgt_batt > 20) {u8g.drawLine(3, 1, 3, 5);} // 20-30
if (lgt_batt > 30) {u8g.drawLine(4, 1, 4, 5);} // 30-40
if (lgt_batt > 40) {u8g.drawLine(5, 1, 5, 5);} // 40-50
if (lgt_batt > 50) {u8g.drawLine(6, 1, 6, 5);} // 50-60
if (lgt_batt > 60) {u8g.drawLine(7, 1, 7, 5);} // 60-70
if (lgt_batt > 70) {u8g.drawLine(8, 1, 8, 5);} // 70-80
if (lgt_batt > 80) {u8g.drawLine(9, 1, 9, 5);} // 80-90
if (lgt_batt > 90) {u8g.drawLine(10, 1, 10, 5);} // 90-100
// RC Batt Lines
if (rc_batt > 5) {u8g.drawLine(126, 1, 126, 5);} // 1-10
if (rc_batt > 10) {u8g.drawLine(125, 1, 125, 5);} // 10-20
if (rc_batt > 20) {u8g.drawLine(124, 1, 124, 5);} // 20-30
if (rc_batt > 30) {u8g.drawLine(123, 1, 123, 5);} // 30-40
if (rc_batt > 40) {u8g.drawLine(122, 1, 122, 5);} // 40-50
if (rc_batt > 50) {u8g.drawLine(121, 1, 121, 5);} // 50-60
if (rc_batt > 60) {u8g.drawLine(120, 1, 120, 5);} // 60-70
if (rc_batt > 70) {u8g.drawLine(119, 1, 119, 5);} // 70-80
if (rc_batt > 80) {u8g.drawLine(118, 1, 118, 5);} // 80-90
if (rc_batt > 90) {u8g.drawLine(117, 1, 117, 5);} // 90-100
}

eEncoderState GetEncoderState() {
  // Считываем состояние энкодера
  eEncoderState Result = eNone;
  CurrTime = millis();
  if (CurrTime >= (LastTime + 5)) {
    // Считываем не чаще 1 раза в 5 мс для уменьшения ложных срабатываний
    LastTime = CurrTime;
    if (digitalRead(pin_Btn) == LOW ) {
      if (ButtonPrev) {
        Result = eButton; // Нажата кнопка
        ButtonPrev = 0;
      }
    }
    else {
      ButtonPrev = 1;
      EncoderA = digitalRead(pin_DT);
      EncoderB = digitalRead(pin_CLK);
      if ((!EncoderA) && (EncoderAPrev)) { // Сигнал A изменился с 1 на 0
        if (EncoderB) Result = eRight;     // B=1 => энкодер вращается по часовой
        else          Result = eLeft;      // B=0 => энкодер вращается против часовой
      }
      EncoderAPrev = EncoderA; // запомним текущее состояние
    }
  }
  return Result;
}

void setup() {
  Serial.begin(9600);
  radioSetup();
  delay(300);
  pinMode(butt1Pin, INPUT);
  pinMode(butt2Pin, INPUT);
  button1.begin();
  pinMode(pin_DT,  INPUT);
  pinMode(pin_CLK, INPUT);
  pinMode(pin_Btn, INPUT_PULLUP);
  select = false;
  bright_var = 100;
  bright_mode = 10;
  lgt_sel = 0;
  lgt_ref = 0;
  lgt_big = 0;
  lgt_matt = 0;
  lgt_ref_br = 100;
  lgt_big_br = 100;
  lgt_matt_br = 100;  
  sel_clk = false;
  currentTime = millis();
  loopTime = currentTime;
if (vol_calibration) calibration();     // калибровка, если разрешена
my_vcc_const = EEPROM.readFloat(1000);  // считать константу из памяти
}

void loop() {
currentTime = millis();

if (currentTime >= (loopTime + 180000)) {
  sleep = true;
}
// Режим сна
if (sleep == true) {
  u8g.sleepOn();
  radio.powerDown();
// Выход из режима сна
if (butt1 == HIGH || butt2 == HIGH || button1.Loop() == SB_CLICK || GetEncoderState() == eLeft || GetEncoderState() == eRight){
  sleep = false;
  loopTime = currentTime;
  radio.powerUp();
}

}
// Обычный режим или первый запуск
if (sleep == false) {
u8g.sleepOff();
// Надпись Loading... и ожидание отклика "Люстры"
if (currentTime < 5000) {  
transmit_data[0] = 1; 
  if (radio.write(&transmit_data, sizeof(transmit_data))) {  
//    trnsmtd_pack++;
    if (!radio.available()) { 
    } else {
      while (radio.available() ) {  
        radio.read(&recieved_data, sizeof(recieved_data));	
		lgt_on = recieved_data[0];
      }
    }
  } else {
//    failed_pack++;
  } 
 
   u8g.firstPage();  
 do {
    splash_screen();     
  } while( u8g.nextPage() ); 
 
}
// Отклик от "Люстры" НЕ получен, сообщаем об этом
if (currentTime > 5500 && lgt_on == 0) {
    u8g.firstPage();  
  do {
    light_is_off();
  } while( u8g.nextPage() );
delay(4000);
}
// Отклик от "Люстры" получен, переходим в рабочий режим
if (currentTime > 5500 && lgt_on == 1) {

//lgt_on = 1;
//
butt1 = digitalRead(butt1Pin);
butt2 = digitalRead(butt2Pin);
//
V = analogRead(A0) * (readVcc() / 1023.0);
rc_batt = map(V, 2950, 4100, 0, 100);
//
if (select == false){ 
if (button1.Loop() == SB_LONG_CLICK){
//  delay(600);   
  Serial.println("Selection Mode ON");
  select = true;
  lgt_sel = 1;
  Serial.println(lgt_sel);
}
}
//
if (select == true){

if (butt2 == HIGH) {
  delay(300);
if (sel_clk == false){
  sel_clk = true;
  Serial.println("Selection Click Enable");
} else {
  sel_clk = false;
  Serial.println("Selection Click Disable");
}
}
//
if (sel_clk == false){

if (GetEncoderState() == eRight){ 
  lgt_sel++;
Serial.println("Right");
Serial.println(lgt_sel);
}
if (GetEncoderState() == eLeft){ 
  lgt_sel--;
Serial.println("Left");
Serial.println(lgt_sel);
}
if (lgt_sel > 3) lgt_sel = 1;
if (lgt_sel < 1) lgt_sel = 3;
//
if (button1.Loop() == SB_LONG_CLICK) {
  select = false;
  lgt_sel = 0;
  Serial.println("Selection Mode OFF");
  Serial.println(lgt_sel);
}
}
}
//
if (sel_clk == true){
//
if (lgt_sel == 1) {
  bright_var = lgt_matt_br;
if (bright_mode == 1) {
  if (butt1 == HIGH && butt2 == HIGH) bright_mode = 10;
  if (GetEncoderState() == eRight) bright_var = bright_var + 1;
  if (GetEncoderState() == eLeft) bright_var = bright_var - 1;
  bright_var = constrain(bright_var, 0, 100);
  lgt_matt_br = bright_var;
} else {
  if (butt1 == HIGH && butt2 == HIGH) bright_mode = 1;
  if (GetEncoderState() == eRight) bright_var = bright_var + 10;
  if (GetEncoderState() == eLeft) bright_var = bright_var - 10;
  bright_var = constrain(bright_var, 0, 100);
  lgt_matt_br = bright_var;
}
if (lgt_matt == 0) {
  if (butt1 == HIGH) {
    delay(150);
    lgt_matt = 1;
  }
} else {
  if (butt1 == HIGH){ 
    delay(150);
    lgt_matt = 0;
  }
}
}
//
if (lgt_sel == 2) {
  bright_var = lgt_big_br;
 if (bright_mode == 1) {
  if (butt1 == HIGH && butt2 == HIGH) bright_mode = 10;
  if (GetEncoderState() == eRight) bright_var = bright_var + 1;
  if (GetEncoderState() == eLeft) bright_var = bright_var - 1;
  bright_var = constrain(bright_var, 0, 100);
  lgt_big_br = bright_var;
} else {
  if (butt1 == HIGH && butt2 == HIGH) bright_mode = 1;
  if (GetEncoderState() == eRight) bright_var = bright_var + 10;
  if (GetEncoderState() == eLeft) bright_var = bright_var - 10;
  bright_var = constrain(bright_var, 0, 100);
  lgt_big_br = bright_var;
}
if (lgt_big == 0) {
  if (butt1 == HIGH) {
    delay(150);
    lgt_big = 1;
  }
} else {
  if (butt1 == HIGH) {
    delay(150);
    lgt_big = 0;
  }
} 
}
//
if (lgt_sel == 3) {
  bright_var = lgt_ref_br;
  if (bright_mode == 1) {
  if (butt1 == HIGH && butt2 == HIGH) bright_mode = 10;
  if (GetEncoderState() == eRight) bright_var = bright_var + 1;
  if (GetEncoderState() == eLeft) bright_var = bright_var - 1;
  bright_var = constrain(bright_var, 0, 100);
  lgt_ref_br = bright_var;
} else {
  if (butt1 == HIGH && butt2 == HIGH) bright_mode = 1;
  if (GetEncoderState() == eRight) bright_var = bright_var + 10;
  if (GetEncoderState() == eLeft) bright_var = bright_var - 10;
  bright_var = constrain(bright_var, 0, 100);
  lgt_ref_br = bright_var;
}
if (lgt_ref == 0) {
  if (butt1 == HIGH){ 
    delay(150);
    lgt_ref = 1;
  }
} else {
  if (butt1 == HIGH) {
    delay(150);
    lgt_ref = 0;
  }
}
}
}
//
sprintf(mode, "%02d", bright_mode);
sprintf(bright, "%03d", bright_var);
//
transmit_data[0] = 1;
transmit_data[1] = lgt_ref;
transmit_data[2] = lgt_big;
transmit_data[3] = lgt_matt;
transmit_data[4] = lgt_ref_br;
transmit_data[5] = lgt_big_br;
transmit_data[6] = lgt_matt_br;
transmit_data[7] = 0;

  if (radio.write(&transmit_data, sizeof(transmit_data))) { 
  //  trnsmtd_pack++;
    if (!radio.available()) { 
    } else {
      while (radio.available() ) { 
        radio.read(&recieved_data, sizeof(recieved_data));
		lgt_batt = recieved_data[1];
      }
    }
  } else {
  //  failed_pack++;
  }

//
    u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() ); 

}
}
}


void radioSetup() {
  radio.begin();  
  radio.setAutoAck(1);  
  radio.setRetries(0, 15); 
  radio.enableAckPayload(); 
  radio.setPayloadSize(32); 
  radio.openWritingPipe(address[0]); 
  radio.setChannel(CH_NUM);
  radio.setPALevel(SIG_POWER); 
  radio.setDataRate(SIG_SPEED); 
  radio.powerUp(); 
  radio.stopListening(); 
}

void calibration() {
my_vcc_const = 1.1;                                           // начальаня константа калибровки
Serial.print("Real VCC is: "); Serial.println(readVcc());     // общаемся с пользователем
Serial.println("Write your VCC (in millivolts)");
while (Serial.available() == 0); int Vcc = Serial.parseInt(); // напряжение от пользователя
float real_const = (float)1.1 * Vcc / readVcc();              // расчёт константы
Serial.print("New voltage constant: "); Serial.println(real_const, 3);
Serial.println("Set vol_calibration 0, flash and enjoy!");
EEPROM.writeFloat(1000, real_const);                          // запись в EEPROM
while (1);                                                    // уйти в бесконечный цикл
}

long readVcc() {
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2);
  ADCSRA |= _BV(ADSC); 
  while (bit_is_set(ADCSRA, ADSC)); 
  uint8_t low  = ADCL; 
  uint8_t high = ADCH;
  long result = (high << 8) | low;
  result = my_vcc_const * 1023 * 1000 / result; 
  return result; 
}

Пример для энкодера:

#define pin_CLK 3
#define pin_DT  2
#define pin_Btn 4

unsigned long CurrTime, LastTime;
enum eEncoderState {eNone, eLeft, eRight, eButton};
int EncoderA, EncoderB, EncoderAPrev, counter;
bool ButtonPrev;

eEncoderState GetEncoderState() {
  // Считываем состояние энкодера
  eEncoderState Result = eNone;
  CurrTime = millis();
  if (CurrTime >= (LastTime + 5)) {
    // Считываем не чаще 1 раза в 5 мс для уменьшения ложных срабатываний
    LastTime = CurrTime;
    if (digitalRead(pin_Btn) == LOW ) {
      if (ButtonPrev) {
        Result = eButton; // Нажата кнопка
        ButtonPrev = 0;
      }
    }
    else {
      ButtonPrev = 1;
      EncoderA = digitalRead(pin_DT);
      EncoderB = digitalRead(pin_CLK);
      if ((!EncoderA) && (EncoderAPrev)) { // Сигнал A изменился с 1 на 0
        if (EncoderB) Result = eRight;     // B=1 => энкодер вращается по часовой
        else          Result = eLeft;      // B=0 => энкодер вращается против часовой
      }
      EncoderAPrev = EncoderA; // запомним текущее состояние
    }
  }
  return Result;
}

void setup() {
  pinMode(pin_DT,  INPUT);
  pinMode(pin_CLK, INPUT);
  pinMode(pin_Btn, INPUT_PULLUP); // Кнопка не подтянута к +5 поэтому задействуем внутренний pull-up резистор
  Serial.begin(9600);
  counter = 0;
}

void loop() {

if (GetEncoderState() == eLeft) Serial.println("Left");
if (GetEncoderState() == eRight) Serial.println("Right");

  
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

Здесь, на форуме, тема есть: "Работаем с энкодером", на последних страницах примеры работы от Dimax, на прерываниях. Попробуйте переделать, у меня после попыток запустить на библиотеках взлетело сразу. ИМХО.

sadman41
Offline
Зарегистрирован: 19.10.2016

transmit_data[7] - это восьмой элемент массива, а у вас объявлена размерность в семь элементов - int transmit_data[7]. Измените что-то одно, иначе словите баг с зависанием или порчей значений переменных и будете долго искать его.

nnm4evr
Offline
Зарегистрирован: 30.07.2017

Если имеется ввиду код от Dimax, приведенный ниже,я вставил нужные части в свой код, но он выдает только нули в мониторе порта. Порты энкодера поменять на свои я не забыл если что.

Код:

volatile int enc;

void setup() {               
Serial.begin(9600);
PCICR=1<<PCIE1; //разрешить пренрывание
PCMSK1=(1<<PCINT19)|(1<<PCINT18); //выбрать входы
}


ISR (PCINT1_vect){
static byte old_n=PINC&3; // маска B00000011 что б читать только нужные 2 бита
byte new_n=PINC&3;
if (old_n==1&&new_n==3||old_n==2&&new_n==0) {enc++;}
if (old_n==2&&new_n==3||old_n==1&&new_n==0) {enc--;}
old_n= new_n;
}

 

void loop() {
Serial.println(enc);
}

 

nnm4evr
Offline
Зарегистрирован: 30.07.2017

"int transmit_data[7]"

А разве он не с 0 считает? 0, 1, ...., 7 итого 8 значений?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nnm4evr пишет:
Порты энкодера поменять на свои я не забыл если что.
Оно и видно.

А теперь поменяй правильно. (везде, где надо менять) 

Глядишь, и заработает.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nnm4evr пишет:
0, 1, ...., 7 итого 8 значений?
Ну тогда и объявлять надо было на 8 значений - int transmit_data[8]

bwn
Offline
Зарегистрирован: 25.08.2014

nnm4evr пишет:

Если имеется ввиду код от Dimax, приведенный ниже,я вставил нужные части в свой код, но он выдает только нули в мониторе порта. Порты энкодера поменять на свои я не забыл если что.

Я вот с этим работал. На 4 и 5 пинах, выдает две единицы на щелчок, с библиотекой глючило страшно. Пример из живого проекта:



long oldEncPosition = -999;
long curEncPosition = 0;
byte DACSetStep = 1;
volatile int enc;
int encoderValue = 0;
int DACSetValue = 0;

//-----------------------------------------------------------------

void getEncPosition()
{
  curEncPosition = enc / 2;

  if (curEncPosition != oldEncPosition) {
    if (curEncPosition > oldEncPosition) {
      encoderValue += DACSetStep;

      if (encoderValue > 4095) {
        encoderValue = 4095;
      }
    } else {
      encoderValue -= DACSetStep;

      if (encoderValue < 0) {
        encoderValue = 0;
      }
    }

    oldEncPosition = curEncPosition;
  }
}
//-------------------------------------------------------------

//Обработка энкодера
ISR (PCINT2_vect) {
  ((PIND & 0x20) >> 4)^((PIND & 0x40) >> 5) ? enc++ : enc--;
}
//-------------------------------------------------------------
void setup() {

  pinMode(5, INPUT_PULLUP); //Пины энкодера и инициализация
  pinMode(6, INPUT_PULLUP);
  PCIFR = PCIFR;
  PCICR = 1 << PCIE2; //разрешить прерывание
  PCMSK2 = 1 << PCINT21; //выбрать вход на котором сработает прерывание

}
//----------------------------------------------------------------

void loop(void) {
  //voltMeter();
  //keyResult();
  //dallRead(flagDallRead);
  //lcdShow();
  getEncPosition();
  //temperatureExe();

}
//---------------------------------------------------------------


nnm4evr
Offline
Зарегистрирован: 30.07.2017

Ворота пишет:

nnm4evr пишет:
Порты энкодера поменять на свои я не забыл если что.
Оно и видно.

А теперь поменяй правильно. (везде, где надо менять) 

Глядишь, и заработает.

Разве не только здесь??? Больше вроде там ни где нет выбора портов...

PCMSK1=(1<<PCINT18)|(1<<PCINT19); //выбрать входы

 

nnm4evr
Offline
Зарегистрирован: 30.07.2017

bwn

Сначала в мониторе порта писал 1, но стоит повернуть энкодер в любую сторону, сразу 0 и как энкодер не крути все время 0.

Вот приведенный Вами код, который я использовал сейчас для теста:

long oldEncPosition = -999;
long curEncPosition = 0;
byte DACSetStep = 1;
volatile int enc;
int encoderValue = 0;
int DACSetValue = 0;

//-----------------------------------------------------------------

void getEncPosition()
{
  curEncPosition = enc / 2;

  if (curEncPosition != oldEncPosition) {
    if (curEncPosition > oldEncPosition) {
      encoderValue += DACSetStep;

      if (encoderValue > 4095) {
        encoderValue = 4095;
      }
    } else {
      encoderValue -= DACSetStep;

      if (encoderValue < 0) {
        encoderValue = 0;
      }
    }

    oldEncPosition = curEncPosition;
  }
}
//-------------------------------------------------------------

//Обработка энкодера
ISR (PCINT2_vect) {
  ((PIND & 0x20) >> 4)^((PIND & 0x40) >> 5) ? enc++ : enc--;
}
//-------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP); //Пины энкодера и инициализация
  pinMode(3, INPUT_PULLUP);
  PCIFR = PCIFR;
  PCICR = 1 << PCIE2; //разрешить прерывание
  PCMSK2 = 1 << PCINT19; //выбрать вход на котором сработает прерывание

}
//----------------------------------------------------------------

void loop(void) {
  //voltMeter();
  //keyResult();
  //dallRead(flagDallRead);
  //lcdShow();
  getEncPosition();
  //temperatureExe();
Serial.println(encoderValue);
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

nnm4evr пишет:

bwn

Сначала в мониторе порта писал 1, но стоит повернуть энкодер в любую сторону, сразу 0 и как энкодер не крути все время 0.

>>4 & >>5 - ?????

nnm4evr
Offline
Зарегистрирован: 30.07.2017

bwn пишет:

>>4 & >>5 - ?????

[/quote]

Поменял я их, просто старую версию скинул, когда в самом IDE правил всё, то заметил, а вот в текстовом файле забыл поменять. Но всё равно результат 0 куда бы я не крутил энкодер и как бы я не менял местами порты (программно естевственно). Хотя в библиотеках всё работает нормально, а вот в моём коде не работает совсем.

nnm4evr
Offline
Зарегистрирован: 30.07.2017

Всё. Понял почему 0 все время, у меня энкодер походу сдох, если убрать if (encoderValue < 0) { encoderValue = 0; }, то в минус он крутиться! Щас попробую в свой код внести Ваш код, посмотрим что получится.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nnm4evr пишет:

Разве не только здесь??? Больше вроде там ни где нет выбора портов...

PCMSK1=(1<<PCINT18)|(1<<PCINT19); //выбрать входы

Конечно, нет. 

Ты вообще понимаешь, что там написано? Если да, то ответь себе (мне не обязательно), какое отношение имеют к "PCINT18" и "PCINT19" в шестой строке к "PCIE1" в пятой?

Если надо, читай даташит пока не поймёшь, что там должно быть.

nnm4evr
Offline
Зарегистрирован: 30.07.2017

Скажу сразу, чтобы не было потом вопросов. Я не знаю что это за строчки (кроме тех где порты указаны так как там есть коммент //выбрать входы), могу только предположить, что они как-то связаны с управлением аппаратными функциями контроллера и не связаны с языком C, C# или CPP на котором пишут программы для Windows, Linux и даже MacOS. И как я уже писал ранее, я привык к Object Pascal (Delphi) и пишу на С так как писал бы на Delphi, так как изучал последний более 10 лет, C для меня сейчас слишком сложен в освоении, да и возраст уже не тот чтобы с нуля другой язык программирования изучать. Поэтому изпользую примеры и Google чтобы разбираться хотя бы в C, а про аппаратные коды контроллера я уже молчу, для меня они ещё более тёмный лес чем C, C# и CPP вместе взятые.

PCICR=1<<PCIE1;
PCMSK1=(1<<PCINT19)|(1<<PCINT18);

Откуда я знаю про то что порты это порты (PCINT18 - цифровой 2, PCINT19 - цифровой 3, куда у меня и подключен энкодер), так вот отсюда:

И кстати заработал код из этого сообщения, после того как я между вызовоми чтения с энкодера поставил задержку:

if (GetEncoderState() == eRight){ 
  lgt_sel++;
}
delay(60);
if (GetEncoderState() == eLeft){ 
  lgt_sel--;
}

 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nnm4evr пишет:
Поэтому изпользую примеры

Так тебе и дали пример. Ты его "поменял" и тут же заявил, что "пример от dimax не работает". Это пример от тебя не работает, а не от dimax, родной.

Я тебе задал вопрос

Ворота пишет:

какое отношение имеют к "PCINT18" и "PCINT19" в шестой строке к "PCIE1" в пятой?

Неужели сама постановка вопроса не навела ни на какие мысли? Ладно, скажу проще,  для "PCINT18" и "PCINT19" там нужно не "PCIE1", а что-то другое. Что именно? Ссылку на даташит я тебе дал, там это чёрным по белому написано - поработай хоть немного сам.

Я понял, что код из другого сообщения у тебя типа заработал, так что на этот ты можешь и забить (хотя он лучше и правильнее), но это уж тебе решать, ты хочешь научиться чему-то или взять чужой код и радоваться, что случайно заработало.

nnm4evr
Offline
Зарегистрирован: 30.07.2017

И так. Всё таки использовал я библиотеку GyverEncoder, только использовал в качестве основы пример под названием timer_isr, и теперь всё работает нормально.

Все файлы (включая библиотеки) можно скачать здесь, так же там есть фото того, ради чего я всё это разрабатывал.

 

bwn
Offline
Зарегистрирован: 25.08.2014

nnm4evr пишет:

И так. Всё таки использовал я библиотеку GyverEncoder..................

У каждого свой вкус, сказал Кот, вылизывая себе экстерьер.))))