0

I'm using an Arduino uno and a Nodemcu for making a game with the phone as a WiFi controller. The Nodemcu is the server that receives inputs from the phone connected via WiFi and sends to the Arduino a signal via SoftwareSerial. The Arduino reads the signal and then decides what to do and sends output to TV. It works good but every time the nodemcu sends something, the TV signal gets distorted.

note: the code for the game is not completed

code for 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");
}

code for arduino (note: seems that stackexcange identifies this function as spam so i posted them here ):

#include<SoftwareSerial.h>
#include <TVout.h>
#include <fontALL.h>
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
TVout TV;
//#define debug 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){ //draws sprite of enemy

}


void renderPlayer(int x, int y){  //draws player sprite

}

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); //enable Serial Monitor
  SUART.begin(115200); //enable SUART Port
  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();  //read char
      switch(x){
        case 'a':
          left();
          break;
        case 'b':
          right();
          break;
        case 'c':
          //left and right same time?
          break;
        case 'd':
          shoot();
          break;
        case 'e':
          left();
          shoot();
          break;
        case 'f':
          right();
          shoot();
          break;
        case 'g':
          //left and right at same time?
          shoot();
          break;
      }
    }
    spriteUpdate();
    render();
}

This is the schematic: this is the schematic

  • what is your question? – jsotola Oct 16 at 20:34
1

Software Serial is a pretty crummy library. It disables interrupts while receiving for long periods of time. That causes any other library that uses interrupts to have issues with timing. There are a plethora of other soft serial libraries out there. Try one of those instead. AltSoftSerial comes to mind.

  • Both AltSoftwareSerial and TVout require pin 9 so i can't use them at the same time. – Andrea Oggioni Oct 17 at 17:19
  • OK, like I said there are a large number of them. They aren't hidden. A quick google search should turn up several alternatives for software serial, each with it's own caveats and abilities. – Delta_G Oct 17 at 22:26
0

It works good but every time the nodemcu sends something, the TV signal gets distorted.

That's correct. SoftwareSerial is terrible. Don't use it. When it's sending or receiving data nothing else at all can happen.

If you have to resort to SoftwareSerial then you are using the wrong hardware for your project. Maybe an ESP32 would be a better choice.


Basically you have two software hacks. Both require precise timing and neither is happy if that timing is messed with. To that end both will disable interrupts to stop things interfering. You can use one or the other, but not both.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.