SoftwareSerial мешает TVout

Я использую Arduino uno и Nodemcu для создания игры с телефоном в качестве контроллера WiFi. Nodemcu — это сервер, который получает входные данные от телефона, подключенного через WiFi, и отправляет на Arduino сигнал через SoftwareSerial. Arduino считывает сигнал, а затем решает, что делать, и отправляет вывод на телевизор. Это работает хорошо, но каждый раз, когда nodemcu что-то отправляет, телевизионный сигнал искажается.

примечание: код для игры не заполнен

код для Nodemcu:

#include<SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "SpaceInvaders";
const char* password = "12345678";

IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
ESP8266WebServer server(80);

void setup() {
  SUART.begin(115200);
  Serial.begin(115200);
  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  server.on("/", handle_OnConnect);
  server.on("/0", nope);
  server.on("/1", left);
  server.on("/2", right);
  server.on("/3", left_right);
  server.on("/4", shoot);
  server.on("/5", left_shoot);
  server.on("/6", right_shoot);
  server.on("/7", left_right_shoot);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

void handle_OnConnect() {}

void nope()             {SUART.print(0); server.send(200, "text/html", " "); Serial.println(0);}
void left()             {SUART.print(1); server.send(200, "text/html", " "); Serial.println(1);}
void right()            {SUART.print(2); server.send(200, "text/html", " "); Serial.println(2);}
void left_right()       {SUART.print(3); server.send(200, "text/html", " "); Serial.println(3);}
void shoot()            {SUART.print(4); server.send(200, "text/html", " "); Serial.println(4);}
void left_shoot()       {SUART.print(5); server.send(200, "text/html", " "); Serial.println(5);}
void right_shoot()      {SUART.print(6); server.send(200, "text/html", " "); Serial.println(6);}
void left_right_shoot() {SUART.print(7); server.send(200, "text/html", " "); Serial.println(7);}

void handle_NotFound(){
  server.send(404, "text/plain", "Error: not found");
}

код для arduino (примечание: кажется, что stackexcange идентифицирует эту функцию как спам, поэтому я разместил их здесь):

#include<SoftwareSerial.h>
#include <TVout.h>
#include <fontALL.h>
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
TVout TV;
//#определить отладку 1
#define numberOfEnemies 15
#define maxEnemyMovement 20
#define playerDefaultY 75

int points = 0;
unsigned long int millisLastEnemyMovement = 0;
int enemyMovementDelay = 850; 
int enemyMovement = 0;
bool directionIsRight = true;

struct b {
  int x;
  int y;
  bool shootable;  
} bullet;

struct p {
  int x;
} player;

typedef struct {
  int x;
  int y;
  bool alive;
} Enemy;

Enemy enemyList[numberOfEnemies];

void renderEnemy(int x, int y){ // рисует спрайт врага

}


void renderPlayer(int x, int y){  // рисует спрайт игрока

}

void shoot(){
  if(bullet.shootable){
    bullet.shootable = false;
    bullet.x = player.x;
    bullet.y = 100;
  }
}

void left(){
  if(player.x > 0){
    player.x--;
  }
}

void right(){
  if(player.x < 105){
    player.x++;
  }
}

void spriteUpdate(){
  if(!bullet.shootable){
    bullet.x--;
    if(bullet.x < 0){
      bullet.x = 0;
      bullet.y = 0;
      bullet.shootable = true;
    }
    for(int i = 0; i < numberOfEnemies; i++){
      if(bullet.x > enemyList[i].x && bullet.x < enemyList[i].x + 11 && bullet.y > enemyList[i].y && bullet.y < enemyList[i].y + 8){
        bullet.shootable = true;
        enemyList[i].alive = false;
        points++;
      }
    }
  }
  if(millis() - millisLastEnemyMovement > enemyMovementDelay){
    millisLastEnemyMovement = millis();
    if(directionIsRight){
      enemyMovement++;
      for(int i = 0; i < numberOfEnemies; i++){
        enemyList[i].x++;
      }
    }else{
      enemyMovement--;
      for(int i = 0; i < numberOfEnemies; i++){
        enemyList[i].x--;
      }
    }
    if(enemyMovement == 0 || enemyMovement == maxEnemyMovement){
      directionIsRight = !directionIsRight;
    }
  }
}

void render(){
  TV.delay_frame(1);
  TV.clear_screen();
  renderPlayer(player.x, playerDefaultY);
  for(int i = 0; i < numberOfEnemies; i++){
    if(enemyList[i].alive){
      renderEnemy(enemyList[i].x, enemyList[i].y);
    }
  }

}
void setup()
{
  char x;
  Serial.begin(115200); //включить последовательный монитор
  SUART.begin(115200); //включаем порт SUART
  bullet.x = 0;
  bullet.y = 0;
  bullet.shootable = true;
  for(int i = 0; i < 5; i++){
    enemyList[i] = {4+i*20, 3, true};
    enemyList[i+5] = {4+i*20, 18, true};
    enemyList[i+10] = {4+i*20, 33, true}; 
  }
  player.x = 50;
  TV.begin(PAL, 120, 96);
  while(true){

  }
}



void loop(){
    if (SUART.available() != 0){
      x = SUART.read();  //читаем символ
      switch(x){
        case 'a':
          left();
          break;
        case 'b':
          right();
          break;
        case 'c':
          //влево и вправо одновременно?
          break;
        case 'd':
          shoot();
          break;
        case 'e':
          left();
          shoot();
          break;
        case 'f':
          right();
          shoot();
          break;
        case 'g':
          //влево и вправо одновременно?
          shoot();
          break;
      }
    }
    spriteUpdate();
    render();
}

Это схема: это схема

, 👍0

Обсуждение

какой у Вас вопрос?, @jsotola


2 ответа


Лучший ответ:

0

Software Serial — довольно убогая библиотека. Он отключает прерывания при приеме в течение длительных периодов времени. Это приводит к тому, что любая другая библиотека, использующая прерывания, имеет проблемы с синхронизацией. Существует множество других программных серийных библиотек. Вместо этого попробуйте один из них. На ум приходит AltSoftSerial.

,

И AltSoftwareSerial, и TVout требуют контакта 9, поэтому я не могу использовать их одновременно., @Andrea Oggioni

Хорошо, как я уже сказал, их большое количество. Они не скрыты. Быстрый поиск в Google должен найти несколько вариантов software serial, каждый со своими предостережениями и возможностями., @Delta_G


0

Он работает хорошо, но каждый раз, когда nodemcu что-то отправляет, телевизионный сигнал искажается.

Верно. SoftwareSerial ужасен. Не используйте его. Когда он отправляет или получает данные, ничего другого произойти не может.

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


По сути, у вас есть два взлома программного обеспечения. Оба требуют точного времени, и ни один из них не будет доволен, если это время испорчено. С этой целью оба отключат прерывания, чтобы не мешать. Вы можете использовать одно или другое, но не оба.

,