0

I wrote a mix of python code and arduino code to make this work. I am sending an array of numbers (audio) to the HC-05 bluetooth module/arduino uno (these are both set to communicate via serial at 115200 baud, at least that is what I set for both (Serial.begin(x) for arduino and through AT commands for HC-05) ranging from 0-4095 as strings from python via bluetooth (bluetoothsocket(RFCOMM)).They are received character by character in the arduino and read into an array which will convert the char array into the single original unsigned int. Up to there I can confirm that chars were received and definitely constructed into integers. Those integer values are passed into a 12-bit DAC via I2C (SDA (A4)/SLC (A5) pins on the arduino. On the webpage (https://learn.adafruit.com/mcp4725-12-bit-dac-tutorial/using-with-arduino) it says that to increase the speed for the transmission you write this "TWBR = 12; // 400 khz" in the arduino script, I'm guessing. Otherwise the DAC will transmit at 100kHz; so I set the transmission speed to 400kHz for the DAC. When I connect the DAC output to the 3.5mm breakout/earbuds I only hear crackling, absolutely no "sound". The earbuds work just fine on my laptop, so the problem is something else. The DAC definitely outputs a voltage (triangle wave file from webpage works) and I tried two 3.5mm breakout boards (maybe shoddy soldering work?). Does anyone have an idea of what the issue could be or steps I could take to find what the error is? My guess is that somewhere the transmission rates/bit transfers do not line up, but that is what I'm trying to find out by asking.

On the python side, the code more or less looks like this:

    *initializing socket, setting to non-blocking socket,etc..

for i in range((1000)):  #just to test, the file Id like to send is maybe 300,000 strings
    HC05_socket.send(soundchars[i])

And this is the arduino code:

#define ledPinr 4
#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

int wait =10000;  //

void setup() {
  // put your setup code here, to run once:
pinMode(ledPinr, OUTPUT);
  digitalWrite(ledPinr, LOW);
Serial.begin(115200);
dac.begin(0x62); 
TWBR = 12; // 400 khz  done in library
Serial.setTimeout(wait);   // for now
}

void loop() {
  // Read serial input:
 char val[4]; // length 4  for 12-bit resolution


if (Serial.available()){
digitalWrite(ledPinr, LOW);


    Serial.readBytesUntil(',', val, 4);  


 int num = atol(val);

dac.setVoltage(num, false);
Serial.print(num);

}


if (Serial.available()==0){
digitalWrite(ledPinr, HIGH);
}

}

Note: ignore the LED code lines, that is just to have an idea of the data flow as I run the program.

user P520
  • 317
  • 2
  • 10

1 Answers1

0

There are many reasons that can lead to crackling audio especially in these kind of setups (as I'm sure you're aware).

A couple of things :

  1. Although in the example you link it says to write TWBR = 12, if you look at the source code of the library it checks for the #define TWBR macro. So I would change your code to have #define TWBR 12 before your setup() function.
  2. How often are you receiving the bluetooth data? It doesn't look like you are handling what's happening when you receive no data the DAC will just freeze on whatever value you wrote last
  3. Make sure you are calling the right address -> you didn't mention if A0 is connected to VCC in your setup.

First, be sure to call begin(addr) where addr is the i2c address (default is 0x62, if A0 is connected to VCC its 0x63)

Side notes:

  • In my experience people try to avoid using atol(). If you look at adafruit's examples they use pgm_read_word() instead.
  • 12 Bit isn't very high audio resolution for audio playback so most audio will be distorted (other than very basic digital sounds)
  • Make sure the audio you're sending from Python is playable (I don't know what your test case is)

In the end it could always be the soldering but I think it will be unlikely.

WoodyDev
  • 1,386
  • 1
  • 9
  • 19