ARDUINO Лазерный тир

Digiprog-Master

✩✩✩✩✩✩✩
19 Июн 2023
4
0
Всем привет, ребят! Помогите разобраться новичку...

Идея следующая. Есть бластер и мишень.
1. На бластере установлен лазерный модуль, OLED экран (со счетчиком патронов и попаданий), кнопка (спусковой крючок), радио-модуль RF24L01 (с антенной).
2. На мишень установлен модуль фоторезистора, зуммер, радио-модуль RF24L01 (с антенной).

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

Все хорошо, первый выстрел и попадание фиксируются! НО! Последующие фиксируются в Serial Monitor, но не передаются мишенью на бластер, пока не перезагрузишь мишень.

Скетчи прилагаю.

З.Ы.

Схема для большинства тут наипростейшая, потому прошу сильно не ругаться))
Мишень:
#define SHOT_PIN 3
#define BUZZ_PIN 4
#include <SPI.h>          // библиотека для работы с шиной SPI
#include "nRF24L01.h"     // библиотека радиомодуля
#include "RF24.h"         // ещё библиотека радиомодуля
RF24 radio(9, 10);
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte data;
void setup() {
  pinMode(BUZZ_PIN, OUTPUT);
  pinMode(SHOT_PIN, INPUT);
  Serial.begin(9600);
  radio.begin();              // активировать модуль
  radio.setAutoAck(0);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    // (время между попыткой достучаться, число попыток)
  radio.enableAckPayload();   // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах
  radio.openWritingPipe(address[0]);  // мы - труба 0, открываем канал для передачи данных
  radio.setChannel(0x69);             // выбираем канал (в котором нет шумов!)
  radio.setPALevel (RF24_PA_MAX);   // уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_250KBPS); // скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  //должна быть одинакова на приёмнике и передатчике!
  //при самой низкой скорости имеем самую высокую чувствительность и дальность!!
  radio.powerUp();        // начать работу
  radio.stopListening();  // не слушаем радиоэфир, мы передатчик   // открыть порт для связи
}

int shot;
void loop() {
  shot = analogRead(SHOT_PIN);
  Serial.println(analogRead(SHOT_PIN));  // читаем и выводим
  delay(10);
if (shot < 600) {
  tone(BUZZ_PIN, 100);  // пищать на пине 3, 1 кГц
  delay(500);
  noTone(BUZZ_PIN);      // не пищать
  delay(500);
  Serial.println("SHOT");
  Serial.println(data);
  radio.write(&data, sizeof(data));
  data++;
  }
else if (shot > 600)
  noTone(BUZZ_PIN);
}
БЛАСТЕР:
#define BTN_PIN 3   // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#define BLASTER_PIN 5 // пин вывода лазера

#include <GyverOLED.h> //подключаем библиотеку экрана
#include "GyverButton.h" //подключаем библиотеку кнопки
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(9, 10);
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
GyverOLED<SSD1306_128x32, OLED_NO_BUFFER> oled;
GButton butt1(BTN_PIN);

int ammo = 9; // Количество патронов
int got = 0; // Количество попаданий
unsigned long timer1;

void setup() {
  pinMode(BLASTER_PIN, OUTPUT);
  Serial.begin(9600);

  oled.init();        // инициализация
  oled.clear();       // очистка
  oled.setScale(2);   // масштаб текста (1..4)
  oled.setCursor(0, 0);    
  oled.print("Патроны: ");
  oled.setCursor(0, 2);
  oled.setScale(2);
  oled.print("Попал: ");

  butt1.setDebounce(10);
  butt1.setClickTimeout(10);
  butt1.setTimeout(1500);

  radio.begin();              // активировать модуль
  radio.setAutoAck(0);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    // (время между попыткой достучаться, число попыток)
  radio.enableAckPayload();   // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах

  radio.openReadingPipe(1, address[0]);   // хотим слушать трубу 0
  radio.setChannel(0x69);     // выбираем канал (в котором нет шумов!)

  radio.setPALevel (RF24_PA_MAX);   // уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_250KBPS); // скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  //должна быть одинакова на приёмнике и передатчике!
  //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

  radio.powerUp();        // начать работу
  radio.startListening(); // начинаем слушать эфир, мы приёмный модуль

}
       

void loop() {

  butt1.tick();  // обязательная функция отработки. Должна постоянно опрашиваться
  oled.update();
  oled.setCursor(100, 0);
  oled.setScale(2);
  oled.print(ammo);
  oled.setScale(2);
  oled.setCursor(80, 2);    
  oled.print(got);

if (butt1.isHold()) {
    ammo = 9;
    got = 0;
    oled.update();
    oled.setScale(2);
    oled.setCursor(0, 0);    
    oled.print("Патроны: ");
    }
if (ammo == 0) {
    oled.update();
    oled.setCursor(0, 0);
    oled.setScale(2);
    oled.print("NO ammo!");
    }

if (butt1.isPress() && ammo > 0) {
  digitalWrite(BLASTER_PIN, HIGH);
  delay(10);
  digitalWrite(BLASTER_PIN, LOW);
  ammo--;
   }

if (millis() - timer1 >= 10) {  // ищем разницу
    timer1 = millis();// сброс таймера
        byte pipeNo, gotByte;
        while (radio.available(&pipeNo)) {        // слушаем эфир со всех труб
              radio.read(&gotByte, sizeof(gotByte));  // чиатем входящий сигнал
              Serial.print("Recieved: ");
              Serial.println(gotByte);
              Serial.println("SHOT");
              got++;
    }
    }              
 

  }
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,200
1,287
Москва
Неужели код такой большой, что не помещается в открытом виде ?
Задать вопрос надо так. что бы отвечающим было максимально комфортно отвечать, а не создавать дополнительные приключения.

Это ведь код мишени ?
Targer_1_0.ino:
#define SHOT_PIN 3
#define BUZZ_PIN 4

#include <SPI.h>          // библиотека для работы с шиной SPI
#include "nRF24L01.h"     // библиотека радиомодуля
#include "RF24.h"         // ещё библиотека радиомодуля

RF24 radio(9, 10);
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte data;

void setup() {
  pinMode(BUZZ_PIN, OUTPUT);
  pinMode(SHOT_PIN, INPUT);
  Serial.begin(9600);
  radio.begin();              // активировать модуль
  radio.setAutoAck(0);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    // (время между попыткой достучаться, число попыток)
  radio.enableAckPayload();   // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах

  radio.openWritingPipe(address[0]);  // мы - труба 0, открываем канал для передачи данных
  radio.setChannel(0x69);             // выбираем канал (в котором нет шумов!)

  radio.setPALevel (RF24_PA_MAX);   // уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_250KBPS); // скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  //должна быть одинакова на приёмнике и передатчике!
  //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

  radio.powerUp();        // начать работу
  radio.stopListening();  // не слушаем радиоэфир, мы передатчик   // открыть порт для связи
}


int shot;

void loop() {
  shot = analogRead(SHOT_PIN);
  Serial.println(analogRead(SHOT_PIN));  // читаем и выводим
  delay(10);
if (shot < 600) {
  tone(BUZZ_PIN, 100);  // пищать на пине 3, 1 кГц
  delay(500);
  noTone(BUZZ_PIN);      // не пищать
  delay(500);
  Serial.println("SHOT");
  Serial.println(data);
  radio.write(&data, sizeof(data));
  data++;
  }
else if (shot > 600)
  noTone(BUZZ_PIN);
}
 
  • Лойс +1
Реакции: Digiprog-Master

Digiprog-Master

✩✩✩✩✩✩✩
19 Июн 2023
4
0
Это мой первый пост) На будущее учту) Да, все верно, это код мишени
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,200
1,287
Москва
Ну я вот не вижу по передатчику проблем, кроме того, что выключается звук постоянно, а он будет выключаться постоянно. И это при том, что он выключается при попадании.

Это мой первый пост) На будущее учту) Да, все верно, это код мишени
Не надо на будущее. Можно на настоящее, стоит отредактировать свой пост, удалить архи и вставить два кода с использованием соотв. тега.
 
  • Лойс +1
Реакции: Digiprog-Master

Старик Похабыч

★★★★★★★
14 Авг 2019
4,200
1,287
Москва
Немного поглядел код приемника, он гораздо хуже чем код передатчика..
1) Получать данные с передатчика надо без задержек - ограничивать частоту передачи должен передатчик исходя из разумных принципов, но т.к. данные отправляются только при попадании, а попадание зависит от выстрела, то чаще чем жать на кнопку данные приходить не будут. Это нормально.
2) обновлять дисплей каждый цикл loop не надо, это долго, и по времени выйдет дорого для остального. Обновлять нужно опять же по событиям. А событий тут несколько: нажатие на кнопку (выстрел) - уменьшается число патронов, и попадание в мишень - приходит сигнал от мишени.

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

Еще прилично ускорить программу поможет вывод в монитор порта информации более сжато и на более высокой скорости, я всегда ставлю 115200.

Если подвести итог: Первый вывод на дисплей надо сделать в конце setup, а все остальный по событию.
 
  • Лойс +1
Реакции: Digiprog-Master

Digiprog-Master

✩✩✩✩✩✩✩
19 Июн 2023
4
0
Честно говоря, запутался от слова совсем. Таймер на миллис только в качестве эксперимента был вставлен...(И то, только потому, что использовались в начале самые простые приемник и передатчик 433 Мгц из набора)
Мне бы репетитора за деньги, чтоб вместе, по удаленке код поправить... наглядно когда, оно понятнее...Может есть тут ребята, кто возьмется за такое? )))
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,200
1,287
Москва
@Digiprog-Master, по поводу приема и передачи пример: 2 человека, один кидает другом мячи , первый передает, второй принимает. Если второй будет читать газету и раз в 10 секунд стараться поймать мяч, то понятно что у него получиться, причем 1-ый будет кидать мячи как попало, но в основном постоянно. а вот если будет наоборот: первый читая газету время от времени кидает мяч второму, тогда как второй постоянно готов ловить - все будет хорошо.
 
  • Лойс +1
Реакции: Digiprog-Master

Digiprog-Master

✩✩✩✩✩✩✩
19 Июн 2023
4
0
@Старик Похабыч, теорию понял. Как реализовать правильно...вот вопрос) У меня явно не хватает базы. Я тут приобрел книгу на вайлдбериз "Паоло Аливерти. Изучаем ардуино. Руководство для начинающих". Прочту книгу, попробую поправить код сам. А потом напишу сюда по результату.