[Raspberry Pi] Bluetooth Audio Headphone

Bluetooth Audio Device with Raspberry PI


Raspberry pi with Bluetooth again.
Last time I connected my DualShock 4 controller to raspberry pi.
This time, my motivation was to use Bluetooth audio headset using Raspberry pi.
I am not sure if this will give me any new project ideas.
Many people have already managed streaming Bluetooth audio from the raspberry pi.
There are a lot of creative projects available.
I hope I can make something unique by learning the Bluetooth audio with raspberry pi.

Setup
I was thinking this would be super easy and just need to work on the pulseaudio. 
This was a bad thought...
Because of this, I created unnecessary problems and took me about 3 hours to make it work.
I added "Note" at the very end of this post if you are interested in what happened.
Anyway, what I learned was that Bluetooth is a little bit tricky depending on the hardware and OS version.
I would highly recommend to double check the hardware and software versions before you start.
    This is the one of the great site to read through.

1. Check hardware version
Hardware version can be referred from cpuinfo file.
$ cat /proc/cpuinfo
When the information is displayed, you can scroll down and find the "Hardware" and "Revision" info.
In my case:
Hardware    : BCM2835
Revision      : a02082

For the relationship between the raspberry pi model and revision number, you can refer to this
I am referring to new style revision code and my hardware is model 3B.
a02082 3B 1.2 1GB Sony UK

If your model is 3B+ with latest raspbian image, I think you can simply follow this.

2. Check OS version
For OS version, you can check os-release file. 
$ cat /etc/os-release

My version is "Stretch". 


3. Testing
You can use desktop Bluetooth icons to pair and connect the device, but here I tried with bluetoothctl.
$ bluetoothctl
After running the bluetoothctl, you can turn on the agent and set it to the default.
agent on
default-agent
Now you are ready to scan the BT devices, and set the headset to pairing mode.
Then type the following command in the bluetoothctl terminal.
scan on

Once your headset is discovered, you will see something like this in the terminal.
[NEW] Device XX:XX:XX:XX:XX:XX  

"XX:XX:XX:XX:XX:XX" is your controller MAC address and type the following command with the MAC address.
Connect XX:XX:XX:XX:XX:XX

Once you see the message "Connection successful", your headset is connected, and last thing you may want to do is remember the device so that it is automatically connected next time.
Trust XX:XX:XX:XX:XX:XX

Now you are ready, and you can close the bluetoothctl by typing "quit".
Before play any audio file, make sure the Bluetooth audio device is selected as playback device.
To do so, right click the volume icon and select the device you want to send the audio.
Try play the audio file, youtube, or any others, and you will hear the audio from your headset! 

You can disconnect the controller from upper right BT icon by selecting "Headset name" > "Disconnect".

Note:
As I mentioned previously, I made big mistake by installing pulseaudio.
Somehow, I was thinking pulseaudio is the must and installed it without checking anything.
Then, I paired my Bluetooth headset without any problem.
I can see my desktop BT icon as connected to the device I want.
Audio device is selected through volume control icon.
However, I could not hear anything...

I run the command "pacmd" to  "list-cards" and what I noticed was there is no BT device indexed...
Just alsa device... hmm...

Then I killed pulseaudio process and restarted, run the "systemctl" command to check the status.
$ sudo systemctrl status bluetooth*

The error message I got was something like below. 
            bluetoothd "unable to get connect data for headset"
From this point, I spend lots of time to solve issue by looking at system, config, and other files.
Until, until I actually found that just simply remove the pulseaudio.
It is always better to read RaspberryPi.org documentation...
It says:
In Jessie, we used PulseAudio to provide support for audio over Bluetooth, but integrating this with the ALSA architecture used for other audio sources was clumsy. For Stretch, we are using the bluez-alsa package to make Bluetooth audio work with ALSA itself. PulseAudio is therefore no longer installed by default, and the volume plugin on the taskbar will no longer start and stop PulseAudio. From a user point of view, everything should still work exactly as before – the only change is that if you still wish to use PulseAudio for some other reason, you will need to install it yourself.

So for the people who see the similar errors, please try removing the pulseaudio ;)
$ sudo apt-get remove --purge pulseaudio

After removing pulseaudio, you can check the bluetooth status with "systemctl" and it should be working now.

Some people might still want to use pulseaudio.
If that is the case, this blog by Youness might help.

Good luck and thank you for reading!




[Raspberry Pi] Servo Control Using DS4 Controller

Raspberry Pi servo control using DS4 controller

In the previous post here,  I successfully connected DS4 controller to Raspberry Pi.
It is time for me to control something using this framework.
The easiest way for me is to control the servo using DS4 input events as I have the servo controller board and tilt & pan servos from Adafruit.
My goal is to use joystick on the DS4 to control the pan & tilt of servo and see how it works.
I expect it would not be so great using joystick as it is a bit sensitive and may be difficult to control servo naturally or precisely. 
Well, let's see how it goes...


Setup
As always, I am using Raspberry Pi 3 Model B (not Plus) for this setup.
The setup looks like this in my environment.
Connecting DS4 to Raspberry Pi can be referred to my previous work here
Also, the using Adafruit servo controller shield board and pan & tilt servo kit can be referred to my previous work here as well.

Adafruit servo controller shield board requires the external power supply but you may be able to use Raspberry Pi 5V by connecting the power and ground pins to the shield board depending on the servo you use.


                          


My approach:
My approach here is to obtain the variation from the default (center) position of the joystick data and convert the number to the servo control signal with a simple scale factor.
Something like this.

    Servo value = (Joystick current value - Joystick center value) x scale factor

To do this, I need to understand the DS4 joystick operation and range of the return values.

There are so many descriptions if you google it but what I did was to add the following line in the python. 

    print (gamepad.capabilities(verbose=True))

This will give you the default value and maximum and minimum value of the each event of the input device.

From this message, left joystick returns 127 as the center value and maximum 255 and minimum 0. 

This means the maximum variation value that I get from joystick is 128 and minimum is -127.

    Maximum variation value = 255 - 127 = 128

    Miminum variation value = 0 - 127 = -127

I just want to move the servo around +/-90 degrees horizontally, and my servo range is as below.

    +90: 570
    0: 370    
    -90: 170

Based on the above, I decided the equation to be like this.

    Servo value = (Joystick current value - 127) x 1/10

One thing that I cannot forget is that I am using evdev and it only returns the input event when there is a change in the value.

This means if I move the joystick to the all the way left or right, the joystick value does not change from the point which results in no servo movement. 



Notes:
Before moving forward, I would recommend to double check the minimum and maximum rotations of your servo. 
Joystick is sensitive and servo might go crazy if the tuning is not done properly.
I would also recommend to place the servo securely with something.

In my case, I used cramp and place it on my desk tightly.


Python code for testing
Now the time to implement the code for both DS4 joystick and servo control.
As I mentioned above and same as my previous work, I used evdev and python for this quick example.
    *** Depending on the python version, you may get different result and my python version is 2.7.13.

If you need the input event numbers of your controller, you can use the following commands to idendify the numbers.


Check input events:
$ ls /dev/input

Install input-utils:
If you do not know which event is mouse or keyboard, follow this.

$ sudo apt-get install input-utils
$ lsinput    

Video:
Here is the video of the quick test.
 

Example:

This is the python example code.

#!/usr/bin/python

from Adafruit_PWM_Servo_Driver import PWM
import time

from evdev import InputDevice, categorize, ecodes, KeyEvent
gamepad = InputDevice('/dev/input/event7')
absMed = 128

pwm = PWM(0x40)

servo0Min = 60
servo0Mid = 360
servo0Max = 660

pwm.setPWMFreq(60)
pwm.setPWM(0, 0, servo0Mid)
time.sleep(1)

step0 = servo0Mid
step0Var = 0

for event in gamepad.read_loop():
    if event.type == ecodes.EV_ABS:
 if event.code == 0 and abs(event.value-absMed) > 20:
  step0Var = (event.value - absMed)/10
  print ('step0Var:' + str(step0Var))
  print ('step0   :' + str(step0))
      step0 += step0Var
  if step0 > servo0Max:
   step0 = servo0Max
  elif step0 < servo0Min:
   step0 = servo0Min
      pwm.setPWM(0, 0, step0)
  step0Var = 0

Crate a python script file as below and copy&paste the above code.
nano ds4-servo-test.py
Run the python script.
python ds4-servo-test.py
Press any buttons on the DS4 and you will see the outputs in the terminal.
Done!



Connecting DS4 to Raspberry Pi over USB or BT

Connecting DS4 to Raspberry Pi

In the previous post here,  I was using python evdev module to capture the USB data.
This time I tried to connect gaming controoler over BT or USB
Connecting gaming controller to Raspberry Pi expands more application to play with.
I thought it would be very useful to make DS4 work with Raspberry Pi so that I can potentially controll various  things that I connected to Raspbery Pi, such as sensors, servos, and so on.
Since I have experienced evdev previously, I will use the same and obtain the input event data from DS4.

Setup
For this setup, I am using Raspberry Pi 3 Model B (not Plus).
To connect DS4 to Raspberry Pi, there are a few ways and I tried 2 method here which is using USB or BT. 
    *** You can also use Playstation USB adapter 

1. Using USB
This is the easiest method and you just need to connect DS4 to Raspberry Pi using micro USB cable.
After connecting DS4, you can check if the controller is recognized using "dmesg" command or something.
In the "/dev/input/" directory, you should see the new event number.

2. Using BT
Using BT is a little bit more complecated, and it might not be stable in some cases.
Here is what I did and it worked.
$ sudo apt-get update
$ sudo bluetoothctl
After running the bluetoothctl, you can turn on the agent and set it to the default.
agent on
default-agent
Now you are ready to scan the BT devices, and prepare for DS4 to enter the pairing mode.
To enter the pairing mode, you press "Share" button and "PS" button at the same time and hold it until the front LED starts flashing.
Then type the following command in the bluetoothctl terminal.
scan on

Once your DS4 is discovered, you will see something like this in the terminal.
[NEW] Device XX:XX:XX:XX:XX:XX Wireless Controller

"XX:XX:XX:XX:XX:XX" is your controller MAC address and type the following command with the MAC address.
Connect XX:XX:XX:XX:XX:XX

If DS4 stoped flashing by the time you run the above command, press "Share" and "PS" button again and do the same.
Once you see the message "Connection successful", your DS4 is connected, and last thing you may want to do is remember the device so that it automatically connects next time when you press "PS" button.
Trust XX:XX:XX:XX:XX:XX

Now you are ready, and you can close the bluetoothctl by typing "quit".
To double check the connection, you should see the new event number in the "/dev/input/" directory.
You can disconnect the controller from upper right BT icon by selecting "Wireless Controller" > "Disconnect".
When you press "PS" button next time, it should automatically connected. 

                  

3. Testing
Next thing is to make sure if the data is received properly. 
I used "joystick" package and here is how to install and use it.

Install joystick:
$ sudo apt-get install joystick
Run joystick software:
$ sudo jstest /dev/input/js0
Check input events:
$ ls /dev/input
If you do not know which event is mouse or keyboard, follow this.
Install input-utils:
$ sudo apt-get install input-utils
$ lsinput    

Python code for testing
I think most people want to actually write the code that can receive the data from the input event.
I believe there are multiple ways and I used evdev and python for this quick example.
This is the python example code.
    *** Depending on the python version, you may get different result and my python version is 2.7.13.

In the python script, you need the event numbers, and you can use the following commands to idendify the numbers.

Check input events:
$ ls /dev/input

If you do not know which event is mouse or keyboard, follow this.
Install input-utils:
$ sudo apt-get install input-utils
$ lsinput    
Example:
#!/usr/bin/python

from evdev import InputDevice, categorize, ecodes, KeyEvent
gamepad = InputDevice('/dev/input/event4')

print (gamepad.capabilities(verbose=True))

for event in gamepad.read_loop():
    if event.type != ecodes.EV_SYN:
      print (categorize(event))

Crate a python script file as below and copy&paste the above code.
nano ds4-test.py
Run the python script.
python ds4-test.py
Press any buttons on the DS4 and you will see the outputs in the terminal.
Done!

Raspberry Pi USB Input Device Data Monitor (Part 2)

USB Mouse/Keyboard Data Monitoring Using Raspberry Pi


In the previous post here, I was using python evdev module to capture the USB data.
This time I used python pyusb module since I found a great post by Gourmet Web Design

Setup
Install pip:
$ sudo apt-get update$ sudo apt-get install python-pip
Install puusb module:
$ sudo pip install pyusb
Check input events:
$ ls /dev/input
If you do not know which event is mouse or keyboard, follow this.
Install input-utils:
$ sudo apt-get install input-utils
$ lsinput

If you want to use pyusb to check the input devices, you can refer to this post by Gourmet Web Design



                  



Python Code
This is the python example code.

Example:
import usb.coreimport usb.util
dev = usb.core.find(idVendor=0x093a, idProduct=0x2510)
# was it found?if dev is None:    print usb.core.find()    raise ValueError('Device not found')
# first endpointinterface = 0endpoint = dev[0][(0,0)][0]print(endpoint)
# tell the kernel to detachdev.detach_kernel_driver(interface)
while True:    try:        data = dev.read(endpoint.bEndpointAddress,endpoint.wMaxPacketSize)        print data    except usb.core.USBError as e:        data = None        if e.args == ('Operation timed out',):            continue
# release the deviceusb.util.release_interface(dev, interface)# reattach the device to the OS kerneldev.attach_kernel_driver(interface)

Crate a python script file as below and copy&paste the above code.
nano test.py
Run the python script.
python test.py
Press any buttons on the keyboard or mouse and you will see the outputs in the terminal.
Done!




USB Host Shield for Arduino

USB Host Shield for Arduino to Monitor USB data


Sparkfun has USB host shield that can work with Arduino.
I think this is great for the user who want to monitor USB data during the prototyping phase.
It is also great for my latency test project that I posted previously.
It seems like this is original done by Circuits@Home and it is super great work!
This post will focus on the setup of the tool and hopefully I can use this for other projects that I am working on.

Setup
Software preparation:
Launch the Arduino IDE.
There is library available through the library manager.
To launch the Library Manager, follow this.

Sketch > Include Library > Manage Libraries...

In the Library Manager, there is a search bar at the upper right.
Type "USB host shield" and you will find the library by Oleg from Circuit@Home.
In my case "USB Host Shield Library 2.0", and here is the screenshot  after the installation.










After the installation, restart the Arduino IDE and you can now refer to the example codes using the library from "File" menu.

File > Examples > USB Host Shield Library 2.0

So many examples here!

Hardware preparation:
Before you use this board, you need to solder the header pins so that you can stack the board on top of the Arduino.
Once you connect the board to Arduino, make sure the power switch is ON position and you will see the red LED is on. 


Test

For my test, I just used USB mouse.
Connect a USB mouse to the USB connector on the shield board.
From the Arduino IDE, select the exmaples.
I used USB HID descriptor example.

File > Examples > USB Host Shield Library 2.0 > HID > USBHID_desc

Upload the code to the Arduino.
Then, open the "serial monitor" from the Arduino IDE (small icon at the upper right).
You will see the data read from USB mouse as you move the mouse.




















Done!



                  

[AKM Chip Booster] Audio ADC AK5704 PCB Design

Designing a PCB prototype with AK5704 is not so difficult and I show an example with my design. People who are not familiar with AK5704,...