Arduino mega2560 play an mp3 file while reading another file - audio

My setup is built of Arduino Mega2560 with an Adafruit's Music Maker shield.
I am running their "player_simple" example and listen (by earphone) to an mp3 playing in the background.
That's work.
Once I try to read additional binary file from the same SD card, in parallel to listening to the music, I hear a white noise through the earphone.
Also, the reading of the binary file from the SD card - fails.
After resetting the Arduino couple of time (by pressing the rst button on the board), I am managing to hear the music but the reading of the binary file never happens.
Questions:
I wonder what I am doing wrong? (see the code below)
Is there an option to read the binary file from the SD card while playing a song (loaded on the same SD card) in the background?
Here is the relevant part of the code:
void setup{
if (! musicPlayer.begin()) { // initialize the music player
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
while (1);
}
Serial.println(F("VS1053 found"));
if (!SD.begin(CARDCS)) {
Serial.println(F("SD failed, or not present"));
while (1); // don't do anything more
}
// Set volume for left, right channels. lower numbers == louder volume!
musicPlayer.setVolume(20,20);
// If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
// audio playing
musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT); // DREQ int
// Play another file in the background, REQUIRES interrupts!
musicPlayer.startPlayingFile("/e01.wav");
myFile = SD.open("S1F25.bin"); // open the binary file
Serial.print (" myfile.read() = ");
Serial.println (myFile.read());
}
void loop() {
volume_control();
if (musicPlayer.stopped()) {
Serial.println("Done playing music");
while (1) {
delay(10); // we're done! do nothing...
}
}
delay(100);
}
void volume_control(){
volume = volume + 1;
if (volume > 90){volume = 90;}
musicPlayer.setVolume(volume,volume);
}

Related

Issues while reading Writting USB data

I am new to Linux operating system, i am trying to interface GSM module with USB,i interfaced USB with GSM module successfully, but i have problem while reading the data from GSM module, i can able to write data to GSM module but while reading its too difficult for me, some time i can able to read data but some time i can't able to read data, here i copy and pasted my code, please go through the code and please let me where i am failing to read data,
i need to write data normally to USB port and data should be read on interrupt based
USB configuration
int init_ttyusb0(int speed,int parity)
{
fd=open("/dev/ttyUSB1",O_RDWR|O_NDELAY|O_NOCTTY|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO);|O_NOCTTY|O_SYNC|O_NDELAY);
perror("open");
if(fd==-1)
{
perror("open");
printf("open usb driver failed\n");
//close(fd);
return 1;
}
saio.sa_handler= signal_handler_IO;
saio.sa_flags=0;
saio.sa_restorer=NULL;
sigaction(SIGIO,&saio,NULL);
fcntl(fd,F_SETFL,FNDELAY);
fcntl(fd,F_SETOWN,getpid());
tcgetattr(fd,&tty);
perror("tcgetattr");
cfsetospeed(&tty,speed);
perror("cfsetospeed");
cfsetispeed(&tty,speed);
perror("cfsetispeed");
tty.c_cflag=(tty.c_cflag&~CSIZE)|CS8; // 8bit character
tty.c_iflag&=~IGNBRK;
// tty.c_lflag=0; // No signaling break process
// tty.c_oflag=0; //No remaping no delay
tty.c_cc[VMIN]=0; // read dosen't block
tty.c_cc[VTIME]=10; //0.5 seconds
tty.c_iflag&=~(IXON|IXOFF|IXANY);
tty.c_cflag|=CLOCAL; // igniore modem controls
tty.c_cflag|=CREAD;
tty.c_cflag&=~(PARENB|PARODD);
tty.c_cflag&=~CSTOPB;
tty.c_cflag&=~CRTSCTS;
tty.c_cflag&=~ICANON; // Disabling cananicle from disbling newline
tty.c_cflag&=~ISIG; // Disabling interrupt signaling bits
// tty.c_iflag&=~(IXON|IXOFF|IXANY); // Disabling software flow control
tty.c_lflag&=~ECHO;
tty.c_lflag&=~ECHOE;
tty.c_lflag&=~ECHONL;
tty.c_lflag&=~(IXON|IXOFF|IXANY);
tty.c_oflag&=~OPOST;
tcsetattr(fd,TCSANOW,&tty);
perror("tcsetattr");
printf("UART configured.....................\n");
}
Interrupt handler
-----------------------
void signal_handler_IO(int status)
{
static int gsm_count
read(fd,&zfc_buffer[gsm_count],sizeof(zfc_buffer));
printf("%s\n",zfc_buffer);
memset(zfc_buffer,0,sizeof(zfc_buffer));
fcntl(fd,F_SETFL,!(O_ASYNC));
}
int main(void)
{
int init_ttyusb0(B9600,0)
while(1)
{
printf("\n eneter option > ");
scanf("%d",&operation);
int m=26;
switch(operation)
{
case 0:
memset(buf_rcv,0,sizeof(buf_rcv));
buf[0]='A';
buf[1]='T';
buf[2]='\r';
buf[3]='\0';
write(fd,"AT\r",3);
usleep((3+25)*100);
fcntl(fd,F_SETFL,O_ASYNC); // Enabling interrupt after write
usleep((3+25)*100);
perror("write");
break;
case 1:
write(fd,"AT+CFUN=1\r",10);
usleep(175000);
fcntl(fd,F_SETFL,O_ASYNC);// Enabling interrupt after write
break;
case 2:
memset(buf,0,sizeof(buf));
strcpy(buf,"AT+CCID\r");
write(fd,"AT+CPIN?\r",9);
usleep(150000);
fcntl(fd,F_SETFL,O_ASYNC);// Enabling interrupt after write
break;
}

MFRC 522 Authentication RESET on Arduino IDE with ESP32

I've been tinkering with the MFRC-522 (RC-522) RFID module for a project.
I'm testing authentication using an old key to check if the RFID's key A for a sector (in my case, Sector 2) is different from the original, if it was, then I would continue, if not I would like to "register" the card by changing the key.
I was caught at the beginning on checking different keys authentication, if I tested a working key and then an incorrect key, it works as expected, but if I test with the incorrect key first, it doesn't allow even the correct key to authenticate.
If I ran the code below everything in serial is
PCD_Authenticate() failed NEW(read): Timeout in communication.
PCD_Authenticate() failed OLD(read): Timeout in communication.
repeatedly but if I flipped old() and neww() I get
OLD WORKS
PCD_Authenticate() failed NEW(read): Timeout in communication.
Why does it work as such?
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 22 // Configurable, see typical pin layout above
#define SS_PIN 21 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
MFRC522::MIFARE_Key old_key = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
MFRC522::MIFARE_Key new_key = {0x23,0x54,0x64,0x3a,0x32,0x66};
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
delay(4); // Optional delay. Some board do need more time after init to be ready, see Readme
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
neww();
old();
}
void old(){
//authentication of the desired block for access
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 15, &old_key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed OLD(read): ");
Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)status));
return;
}else {Serial.println("OLD WORKS");}
//delay(1000);
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
void neww() {
//authentication of the desired block for access
byte status_new = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 15, &new_key, &(mfrc522.uid));
if (status_new != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed NEW(read): ");
Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)status_new));
return;
} else {Serial.println("NEW WORKS");}
//delay(1000);
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
}
So, after reading the datasheet extra hard I came to the conclusion that the state of the card was not ready for the next read, so I came with a fire-all-guns solution that helped my case, The Serial prints are for debugging so if using the code feel free to comment them out.
bool reselect_Card() {
//-------------------------------------------------------
// Can also be used to see if card still available,
// true means it is false means card isnt there anymore
//-------------------------------------------------------
byte s;
byte req_buff[2];
byte req_buff_size=2;
mfrc522.PCD_StopCrypto1();
s = mfrc522.PICC_HaltA();
Serial.print("Halt Status: ");
Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)s));
delay(100);
s = mfrc522.PICC_WakeupA(req_buff,&req_buff_size);
Serial.print("Request: ");
Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)s));
Serial.print("ATQA : ");
Serial.println(dump_byte_array_to_string(req_buff,req_buff_size));
delay(100);
s = mfrc522.PICC_Select( &(mfrc522.uid),0);
Serial.print("Selected : ");
Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)s));
if( mfrc522.GetStatusCodeName((MFRC522::StatusCode)s) == F("Timeout in communication.") ) { return false;}
return true;
}

How to perform read and write between Raspberry Pi 4 and Arduino Nano BLE Via Bluetooth?

I am able to connect a Raspberry Pi 4 an and Arduino Nano BLE through bluepy for Rpi4 and ArduinoBLE.h for Arduino Nano BLE. Unfortunately when I try to write from Rpi4 to Arduino Nano BLE, I'm not seeing the expected output for Read and Write. I don't see any perfect example for Arduino Nano BLE since it is recently released hardware with built-in BLE. It would be very helpful if anyone could help me achieve communication between them. Thanks in advance. Below is my code for Raspberry Pi.
import bluepy.btle as btle
p = btle.Peripheral("de:fc:54:87:b0:04")
services=p.getServices()
s = p.getServiceByUUID(list(services)[2].uuid)
c = s.getCharacteristics()[0]
c.write(bytes("2", "utf-8"))
p.disconnect()
And I'm using the Arduino built-in example from the Arduino Nano BLE Library.
#include <ArduinoBLE.h>
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
const int ledPin = LED_BUILTIN; // pin to use for the LED
void setup() {
Serial.begin(9600);
while (!Serial);
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
// set advertised local name and service UUID:
BLE.setLocalName("LED");
BLE.setAdvertisedService(ledService);
// add the characteristic to the service
ledService.addCharacteristic(switchCharacteristic);
// add service
BLE.addService(ledService);
// set the initial value for the characeristic:
switchCharacteristic.writeValue(0);
// start advertising
BLE.advertise();
Serial.println("BLE LED Peripheral");
}
void loop() {
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
// if a central is connected to peripheral:
if (central) {
Serial.print("Connected to central: ");
//prints the centrals MAC address:
Serial.println(central.address());
// while the central is still connected to peripheral:
while (central.connected()) {
// if the remote device wrote to the characteristic,
// use the value to control the LED:
if (switchCharacteristic.written()) {
if (switchCharacteristic.value()) { // any value other than 0
Serial.println("LED on");
digitalWrite(ledPin, HIGH); // will turn the LED on
} else { // a 0 value
Serial.println(F("LED off"));
digitalWrite(ledPin, LOW); // will turn the LED off
}
}
}
// when the central disconnects, print it out:
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
I figured out myself, it was the value in the write which was going wrong all this time. Below is the right one. I hope now you can find this as a perfect solution to connect raspberry Pi 4 and Arduino Nano BLE wirelessly Via Bluetooth.
c.write(bytes("0001".encode())

Configuring and pairing 2 HC-06 Bluetooth modules as Master and Slave using Arduino UNO

I have been trying to establish connection between two HC-06 Bluetooth modules. Pairing has been done. The two modules are communicating. My aim is to send a letter from one module and receive acknowledgment from the other module. The code for the master module is below.
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX, TX
char c;
char s[]="Matched";
int t[]="NotMatched";
void setup()
{
// start the serial communication with the computer
Serial.begin(9600);
Serial.println("Arduino with HC-06 is ready");
// start communication with the HC-06 using 38400
BTserial.begin(38400);
Serial.println("Bluetooth serial started at 38400");
}
void loop()
{
// Read from HC-06 and send to Arduino Serial Monitor
if (BTserial.available())
{
c=(BTserial.read());
if (c=='a')
{
Serial.write(s);
}
else
{
Serial.write(t);
}
}
// Read from Arduino Serial Monitor and send to HC-06
if (Serial.available())
{
c = Serial.read();
Serial.write(c);
BTserial.write(c);
}
}
Similar code is used for the slave module. Except for the 'else' part in the code everything runs right. I receive acknowledgement along with the else portion being printed twice for both the if and else portion of the code i.e 'matched not matched not matched' is printed when it receives char 'a' and 'not matched not matched not matched' is printed when it receives anything other than 'a' . Can you please give me suggestions on what could be wrong.
Have you printed the characters that you are reading?
I had a similar problem and I found that the Bluetooth was receiving garbage characters. The reason was because the standard baudrate, of HC-06 modules, is 9600, so if you change:
BTserial.begin(38400);
to
BTserial.begin(9600);
In both master and slave, it might work.

select() isn't responding to writing on /dev/input/mice

I am writing a program which monitors through select() on the keyboard and mouse device files. It waits for any write operation (this should happen when there is a keystroke or mouse movement) on those files and as soon as there is a write operation, some jobs are executed.
But it's not working. My code is given below.
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<linux/input.h>
#include<linux/uinput.h>
#include<sys/time.h>
#include<unistd.h>
void main()
{
int mouse_fd,kbd_fd,fd_max;
struct input_event ev;
fd_set rfs,wfs;
if((mouse_fd=open("/dev/input/event3",O_WRONLY))==-1)
{
printf("opening mouse device file has failed \n");
}
else
{
printf("opening mouse device file has been successfull \n");
}
if((kbd_fd=open("/dev/input/event2",O_WRONLY))==-1)
{
printf("opening keyboard device file has failed \n");
}
else
{
printf("opening keyboard device file has been successfull \n");
}
FD_ZERO(&rfs);
FD_ZERO(&wfs);
FD_SET(mouse_fd,&rfs);
FD_SET(kbd_fd,&rfs);
FD_SET(mouse_fd,&wfs);
FD_SET(kbd_fd,&wfs);
if(mouse_fd>kbd_fd)
{
fd_max=mouse_fd;
}
else
{
fd_max=kbd_fd;
}
while(1)
{
select((fd_max+1),&rfs,NULL,NULL,NULL);
sleep(2);
if(FD_ISSET(mouse_fd,&rfs))
{
printf("test mouse \n");
}
if(FD_ISSET(kbd_fd,&rfs))
{
printf("test keyboard \n");
}
}
}
When I execute the program it produces output like this,
[root#localhost Project]# gcc select.c
[root#localhost Project]# ./a.out
opening mouse device file has been successfull
opening keyboard device file has been successfull
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
even though I am not pressing any key. Also, the mouse device file is never selected by select(), even though there is a physical mouse movement.
What am I doing wrong?
You need to reinitialize your fd sets before every select call. So, the loop in your program would look like:
while(1)
{
FD_ZERO(&rfs);
FD_ZERO(&wfs);
FD_SET(mouse_fd, &rfs);
FD_SET(kbd_fd, &rfs);
FD_SET(mouse_fd, &wfs);
FD_SET(kbd_fd, &wfs);
select((fd_max+1),&rfs,NULL,NULL,NULL);
// proceed normally
}
Also, per User1's comment on your same question on Stack Overflow, you need to open the devices for reading, because you are trying to read data from them:
// Open device for reading (do you mean to use "/dev/input/mice" here?)
if ((mouse_fd = open("/dev/input/event3", O_RDONLY)) == -1)
Linux includes a select_tut(2) tutorial manpage with explanations of how to use select and an example program which can be useful as a reference. "Select Law" #11 reminds you that you need to reinitialize your fd sets before each call to select.

Resources