Hi !
Im using two HC-05 modules, with my two UNO's with 14.7456Mhz crystals ( swapped and remade an bootloader ), with two 12bit DAC's and 12bit ADC's, and microphone+speaker for each of them. As you can see, Im trying to achieve to-way data transmission - voice, to be more specific. I've changed the crystal to achieve higher bauds ( 460800, 921600 etc ). I spent DAYS trying to get it working... and what I've achieved so far is very poor quality, one way communication. From what I've readen on forum, most "speed" issues comes from Serial.write() implementation and it's slowness. Well, the thing is, that when I connect those two UNO's at baud rate 460800 or higher, the audio quality is just enough for me. The problem came out after I tried a HC-05 connection. It's seems that HC-05 somehow slows down Serial communication! Obviously, I'm using Hardware Serial and its native pins. All I've achieved from it was very distorded low quality voice ( like it was losing half of packets, or slowed 4 times... ). Using the same program, connecting not via HC-05, but by cross RX->TX, TX->RX made perfect results. Is there any way, that HC-05 would slow down UNO's Serial ? I mean, those bluetooth modules are meant to achieve much higher bauds, and so far im only transmitting one-way. I also couldnt find any detailed HC-05 documentation. Most of it was about AT commands etc. Im aware that HC-05 are SPP, not Audio modules, but my target is 8bit samples and ~8000-10000Hz max Here is my code :
As you can see, it includes functions for ADC and DAC reads ( it disables interrupts for a while! ). It's the transmitter program.
#include <SPI.h>
int readvalue;
const int dacChipSelectPin = 10;
const int adcChipSelectPin = 7;
void setup() {
Serial.begin(460800);
pinMode (dacChipSelectPin, OUTPUT);
pinMode (adcChipSelectPin, OUTPUT);
digitalWrite(dacChipSelectPin, HIGH);
digitalWrite(adcChipSelectPin, HIGH);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
delay(5000);
}
// Function to set the DAC, Accepts the Value to be sent and the cannel of the DAC to be used.
void setDAC(int value, int channel) {
byte dacRegister = 0b00110000; // Sets default DAC registers B00110000, 1st bit choses DAC, A=0 B=1, 2nd Bit bypasses input Buffer, 3rd bit sets output gain to 1x, 4th bit controls active low shutdown. LSB are insignifigant here.
int dacSecondaryByteMask = 0b0000000011111111; // Isolates the last 8 bits of the 12 bit value, B0000000011111111.
byte dacPrimaryByte = (value >> 8) | dacRegister; //Value is a maximum 12 Bit value, it is shifted to the right by 8 bytes to get the first 4 MSB out of the value for entry into th Primary Byte, then ORed with the dacRegister
byte dacSecondaryByte = value & dacSecondaryByteMask; // compares the 12 bit value to isolate the 8 LSB and reduce it to a single byte.
switch (channel) {
case 0:
dacPrimaryByte &= ~(1 << 7);
break;
case 1:
dacPrimaryByte |= (1 << 7);
break;
}
noInterrupts(); // disable interupts to prepare to send data to the DAC
digitalWrite(dacChipSelectPin, LOW); // take the Chip Select pin low to select the DAC:
SPI.transfer(dacPrimaryByte); // send in the Primary Byte:
SPI.transfer(dacSecondaryByte);// send in the Secondary Byte
digitalWrite(dacChipSelectPin, HIGH); // take the Chip Select pin high to de-select the DAC:
interrupts(); // Enable interupts
}
uint16_t readADC(int channel) {
uint16_t output;
byte channelBits = channel | 0x00;
channelBits = channelBits << 5;
noInterrupts(); // disable interupts to prepare to send data to the DAC
digitalWrite(adcChipSelectPin, LOW); // take the Chip Select pin low to select the DAC:
SPI.transfer(B00000110);
byte msb = SPI.transfer(channelBits);
byte lsb = SPI.transfer(0x00);
digitalWrite(adcChipSelectPin, HIGH); // take the Chip Select pin high to de-select the DAC:
interrupts(); // Enable interupts
msb = msb & B00001111;
output = msb << 8 | lsb;
return output;
}
void loop() {
readvalue = readADC(0);
Serial.write((readvalue >> 4) & 0xff);
delayMicroseconds(22);
}
Reciever program is just alittle bit different at the end :
void loop() {
if(Serial.available()>0){
readvalue = Serial.read();
setDAC((readvalue << 4) & 0xff0, 0);}
}