Use this forum to chat about hardware specific topics for the ESP8266 (peripherals, memory, clocks, JTAG, programming)

User avatar
By mrburnette
#51177 ESP8266 <=====> 5V Arduino always needs some type of level shifting between the Arduino Send and the ESP8266 Receive (ESP8266 Send to Arduino Receive is a direct connection.)

Now, you have a lots of options.
- Change to a 3.3V Arduino
- Use a resistor divider for lower BAUD rates
- Use a level-shifter for higher BAUD rates

Overview of level shifters: https://learn.sparkfun.com/tutorials/logic-levels
User avatar
By debojitk
#51538
martinayotte wrote:
So you mean, the library does not exist yet!

SPI library already exist, but your own communication protocol isn't.
voltage divider approach does not work well for higher speed

Right, at high speed, the square wave of the signal becomes distorded. MOSFET level shifter is better :
Image

Well, I could not get a level shifter handy so made a direct connection even knowing the fact that it can destroy my nodemcu. However it did not, but someday it would burn so I will definitely get a logic level shifter.
Now I am successfully able to stream data from arduino to esp8266. Actually I am sending PCM signal @38.5k reading from A0 of arduino, and I am able to play the stream using my java program seamlessly. Now I want to send audio data from java program and receive at esp end, send it to arduino via serial and then play using pwm (with some low pass filter to shape the signal).
My concern is, esp is very fast in transmitting data, and with the library I found it can send/receive data at chunks of 2920 bytes. I plan to receive data at esp end and then want to send it to arduino via serial. Arduino is running a 31250hz isr (to generate sound of 31.25khz sample rate) using timer 2. Now the thing is arduino would receive a byte from serial @31250 hz rate, that is pretty low as compared to java to esp sending rate. Here two levels of flow control should be handled.
1. Data from java program to esp (tcp/ip socket communication)
2. Data from esp to arduino (Serial).
Would this setup result in Serial buffer overflow resulting into data loss, as arduino is taking the data at a very lower rate as compared to data rate between java program and esp. AFAIK the tcp/ip flow control is handled inside its protocol implementation, so buffer overflow should not happen between java and esp communication, i am more concerned on the serial part.
Please see the code snippets.
1. Arduino code
Code: Select all#include "Arduino.h"
#include <avr/interrupt.h> // Use timer interrupt library


void setup() {

   /****Set timer1 for 8-bit fast PWM output ****/
   pinMode(9, OUTPUT); // Make timer’s PWM pin an output
   TCCR1B = (1 << CS10); // Set prescaler to full 16MHz,
   TCCR1A |= (1 << COM1A1); // Pin low when TCNT1=OCR1A
   TCCR1A |= (1 << WGM10); // Use 8-bit fast PWM mode, so it will count from 0-255, and the duty cycle would be set by OCR1AL(OCR1A lower byte)
   TCCR1B |= (1 << WGM12);
   //freq calculation: at 16mhz, time taken to count till 255 is (1,000,000/16,000,000)*256usec=16usec
   //freq is 16,000,000/256=62500hz=62.5khz,

   /******** Set up timer2 to call ISR ********/
   TCCR2A = 0; // No options in control register A
   TCCR2B = (1 << CS21); // Set prescaler to divide by 8,
   //i.e., 16,000,000/8=2,000,000 clock tick/sec,
   //so every tick at 500ns (.5us), so to spend 32 usec it needs to count upto 64, 64*.5=32
   TIMSK2 = (1 << OCIE2A); // Call ISR when TCNT2 = OCRA2
   OCR2A = 64; // Set frequency of generated wave=2,000,000/64=31250hz
   sei(); // Enable interrupts to generate waveform!
}

void loop() { // Nothing to do!
}

/******** Called every time TCNT2 = OCR2A ********/
ISR(TIMER2_COMPA_vect) { // Called when TCNT2 == OCR2A
   TCNT2 = 0; // Timing to compensate for ISR run time
   if(Serial.available()){
      uint8_t byte=Serial.read();
      OCR1AL=byte;
   }else{
      OCR1AL=0;// duty cycle is zero, no output
   }
}

2. esp code:
Code: Select all#include "ESP8266WiFi.h"
const char* ssid = "debojit-dlink";
const char* password = "India@123";
uint8_t outBuffer[2920];
uint8_t inBuffer[3000];

const char* host="192.168.0.101";
WiFiClient client;
void setup(){
   Serial.begin(500000);
   setup_connect_as_station();
}
void setup_connect_as_station(){
   Serial.println();
   Serial.print("Connecting to ");
   Serial.println(ssid);
   Serial.print("Configuring access point...");
   /* You can remove the password parameter if you want the AP to be open. */
   WiFi.softAP("ESPAP");
   IPAddress myIP = WiFi.softAPIP();
   Serial.print("AP IP address: ");
   Serial.println(myIP);

   WiFi.begin(ssid, password);

   while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
   }
   Serial.println("");
   Serial.println("WiFi connected ip is");
   Serial.println(WiFi.localIP());
   Serial.println("#################");
   WiFi.printDiag(Serial);
   WiFi.hostname("esp8266");
   WiFi.printDiag(Serial);
}

void loop(){
   const int httpPort = 8086;
   if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      delay(2000);
      return;
   }
   Serial.println("Connected, now receiving...");
   int cnt=0;
   //uint32_t sTime=0;
   while(true){
      int readBytes=client.read(inBuffer,2920);
      if(readBytes>0){
         int writeBytestoSerial=Serial.write(inBuffer,readBytes);
      }
   }
}

3. Java Code running on PC
Code: Select allpackage com.test.socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

public class DataTransceiverSocket extends Thread {
   private ServerSocket serverSocket;
   private SocketAddress remoteSocketAddress;

   public DataTransceiverSocket(ServerSocket serverSocket, String name) throws IOException {
      this.setName(name);
      this.serverSocket = serverSocket;
      // serverSocket.setSoTimeout(10000);
   }

   public void run() {
      while(true){
         System.out.println(getName() + "->Waiting for client on port " + serverSocket.getLocalPort() + "...");
         Socket server = null;
         try {
            server = serverSocket.accept();
            remoteSocketAddress = server.getRemoteSocketAddress();
            System.out.println(getName() + "->Just connected to " + remoteSocketAddress);
         } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            return;
         }
         Sender sender=new Sender(server);
         sender.start();

      }
   }

   public static void main(String[] args) {
      try {
         ServerSocket serverSocket = new ServerSocket(8086);
         Thread t = new DataTransceiverSocket(serverSocket, "T1");
         t.start();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

}
class Receiver extends Thread{
   Socket socket;
   byte buffer[] = new byte[2920];
   public Receiver(Socket socket) {
      // TODO Auto-generated constructor stub
      this.socket=socket;
   }
   @Override
   public void run() {
      try{
         DataInputStream in = new DataInputStream(socket.getInputStream());

         AudioFormat af = new AudioFormat(38500, 8, 1, false, false);
         DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
         SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);

         line.open(af, 2920);
         line.start();
         while (true) {
            try {
               if (in.available() > -1) {
                  int readBytesInterim = in.read(buffer, 0, buffer.length);
                  System.out.print(".");
                  line.write(buffer, 0, readBytesInterim);
               }
            } catch (SocketTimeoutException s) {
               System.out.println("Socket timed out!");
               break;
            } catch (IOException e) {
               e.printStackTrace();
               break;
            }
         }
         line.drain();
         line.stop();
         line.close();
      }catch(Exception ex){
         ex.printStackTrace();
      }
   }
}

class Sender extends Thread{
   Socket socket;
   byte buffer[] = new byte[2920];
   public Sender(Socket socket) {
      // TODO Auto-generated constructor stub
      this.socket=socket;
   }
   @Override
   public void run() {
      while(true){
         try{
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            FileInputStream fis=new FileInputStream("C:\\Users\\debojitk\\Desktop\\test1.bin");
            int readBytes=0;
            while((readBytes=fis.read(buffer, 0, buffer.length))>-1){
               out.write(buffer,0,readBytes);
            }
            fis.close();
         }catch(Exception ex){
            ex.printStackTrace();
         }
      }
   }
}


I am thinking should I implement a timer driver interrupt at esp end as well to synchronize Serial data transmission between arduino and esp.
Sorry, I wrote so many things.
Kindly suggest if my understandings are correct.

Thanks in advance,
Debojit
User avatar
By martinayotte
#51555 BTW, I forgot to ask :
What is that stream content ? In which direction is it going (in or out going from you Java server) ?
If it MP3 Radio streaming, you should look about VS1053 on ESP solution (no need for Arduino UNO).
Some already ported ReadyToUse firmware for that :
viewtopic.php?p=48287#p48287