Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Making a Bluetooth adapter for a Car Phone from the 90's

Another new feature implemented: I'm reporting approximate battery capacity back to the phone so it can be displayed while in a call, based on the voltage of the main power supply from the transceiver:


IMG_E6995.JPG



It correlates pretty closely to battery voltage in the transceiver, except that the voltage does drop significantly when the handset backlight is on, so I'll probably eventually try to account for that by calibrating two different battery level calculations to account for that difference.
 
Here's a video update on a variety of smaller features I've been working on:



Making the phone produce DTMF tones over the call to navigate touch-tone menus was particularly frustrating. The Bluetooth module has a UART command that is supposed to cause the host phone to generate a desired DTMF tone (just pass it a string of one or more ASCII characters of the desired digits). But it didn't work.

I briefly tried sending my own generated DTMF tones through the call, and I got it "working" (the tones could be heard on the other end of the call), but it didn't really work (wasn't detected by touch tone menu systems). I think it was a combination of my DTMF tones not quite being within specs (cleanliness of tones, or dB level requirements), as well as the Bluetooth module performing audio processing to all mic input for noise reduction, voice clarity, etc..

The non-working UART command documentation mentioned that is sends the "AT+VTS" command to the phone, and there's also a UART command for sending any arbitrary AT command to the phone. So I did some searching on the "AT+VTS" command and found conflicting specs on the details of how the passed value is formatted. So I played around with sending raw "AT" commands until I found the format that worked!

So when pressing a dialable button during a call, I both produce my own DTMF tone through the handset for user feedback (but with the microphone temporarily disconnected to avoid indirectly sending the button beep over the call), and also send the UART command to send the "AT+VTS" command to the cell phone (which will produce a correct DTMF tone for some default amount of time determined by the cell phone network).
 
Time for an update. Progress has slowed a lot because I already got the majority of functionality "done" to at least a rough/prototype/proof-of-concept level, and now I'm trying to go back and do things "right" and fix all the issues.

On the software side, I've been generally cleaning up and reorganizing code to make more sense, avoid race conditions between the main "task" loop and interrupt handlers, adding better error handling, etc.

I've implemented some more replica behavior of the original phone that is less exciting than the rest of the project, but helps complete the authenticity of using a vintage car phone:
  • Last call talk time and accumulated talk time are now both persisted in EEPROM, and there's a button sequence to view these stats.
  • Passcode-protected option to reset talk timer stats.
  • Passcode-protected option to view a non-resettable "total talk time".
  • Passcode-protected "credit card number" memory slots, which can be referenced in stored phone numbers without revealing the underlying number.
  • A warning beep can be enabled that will warn you 10 seconds before the end of every minute during a call (per-minute charges used to be expensive!)
  • Support for the "pause" character in a phone number. When calling such a number, it will call the number up to the pause, then when in the call you can press "SEND" again to send the remaining digits as DTMF tones over the call (up to the next "pause", and so on...).

On the hardware side, I've been trying to improve the audio circuitry. I discovered I was misusing my digital pot for volume control, because I passed the audio signal through a coupling cap before passing it into the potentiometer. But the digital pot can only handle voltages between VDD (+5V) and VSS (0V). So I have to pass the 2.5V biased audio signal through the digital pot, and use the 2.5V bias voltage as the reference for the "low" side of the pot so that the attenuated signal remains centered around 2.5V instead of level-shifting based on volume level. This cleaned up some noise and helped with reducing audio pops when switching volume levels.

I added a an inverting unity gain op amp to generate the inverted copy of my audio signal so I can send differential audio to the handset. It's mostly a success. Here's my differential output of a button beep and some voice audio from a call:

IMG_7101.JPG
IMG_7100.JPG



However, I'm getting some really nasty noise in the audio at higher volume levels and ONLY when audio is going to the loudspeaker of the handset. If the audio is going to the ear speaker, then the audio signal is pretty clean. There is absolutely no difference in my circuit between these situations (same positions for the volume pot and all switches, same exact audio source, etc.). Here's an example of the same exact sound at the same volume level, etc., going to the ear speaker and going to the loud speaker:

IMG_7116.JPG
IMG_7115.JPG


The noise seems to pretty consistently start at peaks of waveforms.


Here's a partial representation of my audio circuit now (ignoring microphone audio and the details of how the MCU interacts with the switch):

1648615186723.png


One vague suspicion I have is that I should be buffering the "(Audio + )" signal to the handset to ensure that it has enough "power" to "drive" the handset audio? I don't know if any of these terms are correct, but I feel like better "symmetry" between both audio signals (in terms of what is "driving" the signal) can only be good. I'm thinking I should get another INA105 precision unity gain op amp and set it up as a non-inverting unity gain.

I'm also unsure of whether I set things up properly at the output of my switch and around the digital pot:
  • Is it OK that there's no capacitor involved with biasing the output of the switch? I need the signal to be biased to 2.5V when entering the digital pot to keep the signal within bounds (0-5V) of what the digital pot can handle.
  • Does my direct connection of the "low" end of my potentiometer to +2.5V make sense?
  • Anything else look funky around the switch and potentiometer?
 
Last edited:
rjenkinsgb Do you have any suggestions for improving my audio circuit or what might be causing my strange noise? As of now, I'm just going to throw another op amp at it and cross my fingers without really understanding what could be causing that noise. Yet another order to mouser.com with $8 shipping.
 
It looks like either your power circuit is short of decoupling, or it may be that some decoupling cap(s) in the handset have dried up, so the internal power is not stable when the audio amp starts drawing significant current?
 
I did a bit more testing. I get nearly identical noise with 4 different handsets (one of which was brand new in box, old stock, opened last year).

I never saw this noise when I was doing my original testing and reverse-engineering of the phone (using the original transceiver directly), even at max volume, so I think this rules out the handset as the cause of the problem?

your power circuit is short of decoupling

Could you elaborate on what this means? Would it happen to be related to this 352mV peak-peak noise I see on my power supply (yellow) that directly correlates to the noise in my audio (blue)?


IMG_7120.JPG
 
Yes, that looks very suspicious!
Try adding a decent size electrolytic cap across the power connections?
 
Try adding a decent size electrolytic cap across the power connections?

Just for context, I'm powering my circuit off of the same ~10-12V power supply from the transceiver that powers the handset. I'm using a ST Microelectronics L7805 to regulate that to 5V for my circuit, and I have a 0.22 uF ceramic cap between the input and ground, and a 0.1 uF ceramic cap between the output and ground (found this recommendation somewhere online).

I added a 100 uF electrolytic cap between input and ground, and another between output and ground. No change in the noise.

FWIW, the noise exists on both the original ~12V supply, and on the 5V output of the voltage regulator. Maybe worth noting that it doesn't necessarily mean that the noise is on the positive voltage supply, right? Couldn't it technically be noise on the ground and produce the same scope readings? Is there any meaningful distinction between ground noise and power supply noise? Any way to test this?

Some things I plan to check next:
  • Check the current draw of my circuit. Am I possibly maxing out the current limit of the voltage regulator?
  • Try wiring up a separate power supply for my circuit. Am I possibly drawing too much current from the phone's power supply?
 
Here's some results from measuring amp draw.

My circuit by itself:
~42 mA when idle (paired with a phone via Bluetooth, but not doing anything).
~33 mA with the Bluetooth module disconnected from power.
~20 mA for the MCU alone.

My circuit + handset all together:
~53 mA when idle.
~144 mA with handset backlight and audio circuit on.
~197 mA while producing full volume tone with handset backlight and audio circuit on.

Some conclusions/observations:
  • I'm well within the 1.5 A max output of the voltage regulator for my circuit.
  • My circuit by itself doesn't seem to draw any significant additional amperage when "producing" a sound.
  • Compared to the ~11 mA idle current of the handset by itself, my circuit is an inefficient pig drawing ~42 mA when doing nothing, with only ~9 mA of that being consumed by the Bluetooth module.
  • I need to try a separate power supply for my circuit to determine if the additional amp draw of my circuit is causing the problem.
 
I suspect that the handset internal power decoupling caps have degraded, so the current on the handset cable is varying with the audio rather than being smoothed out to an average level.
 
I suspect that the handset internal power decoupling caps have degraded, so the current on the handset cable is varying with the audio rather than being smoothed out to an average level.

Would your suspicion be consistent with these new observations...?

I tried powering my circuit with a separate 5V power supply (skipping my voltage regulator completely, and the transceiver/handset ~12V power supply is not connected to my circuit in any way). My audio signals are now nice and clean.

When producing sound at high volume in this configuration, the power supply for the handset drops in voltage a bit, and fluctuates vaguely relation to the audio signal. The more interesting part is that when the sound first starts, and the voltage is starting to drop, it looks like this, with the same noise I've been looking at (yellow is AC-coupled view of handset voltage):

IMG_7125.JPG


But once the voltage drop settles, the horrible noise disappears:
IMG_7124.JPG
 
The scope pictures from my previous post are a bit "wrong" because I forgot I had disconnected the second audio input from the inverted audio output (and grounded it). After reconnecting my audio completely, it gets even worse. Voltage drops even more on the handset power supply, and the nasty noise has much higher amplitude AND persists continuously as long as the sound is being played (this is all while my circuit is isolated from the transceiver/handset power supply)

That's 1.2V peak-peak noise!

IMG_7146.JPG
 
Open up the handset and take a photo of the PCB??

I forgot to take pictures, but I had a couple handsets apart to clean them and swap parts around. There are no electrolytic capacitors in there at all. I only see small surface mount capacitors.

Some new observations:
  • I was producing sound with too much peak-to-peak voltage compared to the original phone. After adjusting to match the original phone, the problems with loud sound interfering with digital handset commands is less frequent, but not solved.
  • The nasty noise on the power supply only happens for lower frequency tones now, and the severity seems to increase as tone frequency decreases.
  • Even the original phone hooked up normally without my circuit has similar power supply voltage drop during loud sounds, as well as noise on the power supply that correlates to the shape of the sound signal. So the general power supply fluctuations in relation to sound output is not unique to my circuit. But I haven't seen the really nasty noise on the original phone by itself.
  • Similarly, the digital signal to the handset has voltage fluctuations that correlate to the sound signal, both originally, and with my circuit involved.
  • One substantial difference, and only when connected through the long phone cable running from front to rear of the car, is the "baseline" voltage of the digital signal:
    • With original phone hooked up normally, baseline voltage is is about +150 mV, and increases to about +200 mV (+/- fluctuations correlating with sound signal).
    • With my circuit connected, the same signal has a baseline that is NEGATIVE. About -200 mV. Then it decreases even more negative when playing a loud sound.
  • When connected more directly with shorter wires, the baseline voltage of the digital handset signal is practically exactly 0 V, both with and without my circuit connected. What would be causing it to shift negative vs positive with longer wires involved? Is there any way for me to adjust my circuit to gen my signal's baseline to shift positive with long wires?
  • When there's the nasty noise in the power supply signal, it correlates to a similar nasty noise in my handset digital signal, and that nasty noise spikes the signal even further negative! I think it's these more extreme negative voltage spikes on the digital signal that are causing false readings. I have confirmed that it doesn't even have to correspond with an actual attempted digital command. Just producing sound that induces the nasty noise (while no commands are being sent) will induce "phantom" commands received by the handset, which seem to correlate with nasty negative spikes in the digital signal baseline "idle" voltage level.
 
Here's a demo of some new features I implemented:
  • Caller ID
  • Viewing/changing the Bluetooth name of the car phone adapter.
  • Viewing the Bluetooth name of the paired cell phone.


One small challenge was the combination of the scrolling caller ID and flashing "CALL" text. The handset supports a flashing mode that flashes all text on the screen, which very cleanly flashes the entire text area on/off together. But I don't want the scrolling caller ID to be flashing, so I had to manually overwriting those 4 character positions with spaces, then with "CALL", alternating. Unfortunately, writing characters to the display is slow enough that you can see the word "CALL" updating from left to right. You can see the switch from "native" blinking to manual blinking when the caller ID text first displays.
 
Last edited:
Can you trace the audio input at the handset, just the first two or three components?
Or the output circuit on the original phone?
 
rjenkinsgb I still haven't gotten around to inspecting the audio input/output circuit of the original handset/transceiver, but I have confirmed my hypothesis about the negative spikes on my UART output to the handset being the culprit.

I have returned to using a transistor + resistors to invert the UART output from my MCU, rather than using the MCU's built-in "invert" config for the UART. But instead of connecting the transistor's emitter directly to ground, I now use a resistor there to raise the "low" signal voltage to about +450 mV. This is plenty low enough to be detected as a digital "low" signal when connected directly to the handset, but high enough to keep the "low" signal voltage above zero after the voltage drop across the long wires in the car, and it even keeps the negative noisy spikes above zero. I am now able to use the phone flawlessly in my car without any corrupt output to the handset display.

I know this is more of a band-aid than a true solution to the root cause of the noisy spikes, but it seems to work. I haven't noticed any other negative side effects of the supply/ground noise when playing loud sounds.
 
Time for some updates on the software development side of things. I'll break this into a couple separate posts...

First, I did something recently that I should have done a long time ago: I configured another UART on the MCU so that all "stdio" output is automatically redirected as UART output. This is very easy in Microchip's MPLAB X IDE with the "Code Configurator" tool:

uart_stdio_redirect.PNG


Then I can use standard C functions like "printf()" to log information about what's happening throughout the code. Using a USB-UART adapter, and RealTerm, I can see the logging output on my computer in real time as I test things.

Here's an example of the logging during startup and automatically reconnecting to my cellphone:

startup_logging.PNG


This has been crucial to figuring out some problems. That UART-USB adapter has proven itself very useful many times during this project :)
 
Last edited:
I've had to work around several strange problems. Some of them, I'm not sure if it's a bug in the firmware of the Bluetooth module, or a bug in my cell phone's handling of Bluetooth HFP commands.

Here's a fun one that I am pretty sure is a bug in the latest version of iOS. When an active call is ended from the other end of the call (the person you are talking to hangs up), sometimes I see very strange behavior where my car phone quickly jumps between showing that it is making an outgoing call, actively in a call, and acting like the call ended multiple times in a row. Of course I first assumed that I had a bug in my code, and started combing through it looking for something that could cause this behavior. This is what motivated me to setup logging via UART so I could see what was happening.

So I started logging the call status change events from the Bluetooth module. The call status should simply change from "Active" to "Idle", and the "SCO" (audio connection) should disconnect.

But what I saw was this, in quick succession:
  1. Status: Idle
  2. SCO disconnected
  3. Status: Outgoing
  4. Status: Active
  5. SCO connected
  6. Status: Idle
  7. SCO disconnected
  8. Status: Outgoing
  9. Status: Active
  10. SCO disconnected
  11. Status: Idle
  12. SCO disconnected
This makes no sense at all, because "Outgoing" means placing an outgoing call from my cell phone. This is happening when the call is ending, even if it was originally an incoming call that I answered on my phone.

This seemed to start happening recently (but inconsistently) after upgrading iOS on my iPhone 8, and there's nothing I can do to fix the root cause. So I had to setup a delay in handling changes to call status as a work-around. When the status changes, I handle it immediately if there was no recent status change. But if there was a recent status change, then I defer handling of the status change a short amount of time. I defer it again if another change happens before I've handled the previous change. When I finally handle the change, I do absolutely nothing if the new state is the same as the last state I actually processed. The end result looks like this:

call_ended_bug_logging.PNG


The [handleCallStatusChange] entries in the log are when I'm actually processing the change, so you can see I successfully ignored all the extra status changes. Right now I have the state change handling delay set to 1.5 seconds, and it STILL sometimes isn't a long enough delay, and I end up with strange behavior. I'm not sure I want to increase the delay any more.
 
Last edited:
The next frustration is Caller ID. The Bluetooth module provides a specific Caller ID event that is supposed to conveniently report the Caller ID text. In the configuration software for the Bluetooth module, there is also an option for whether the Caller ID event should provide the text representation if available (i.e., the caller's name), or if it should consistently always provide only the incoming phone number.

I selected the option to prefer the text/name if available, and here's the behavior I observed:
  • For a normal incoming call, I do receive the name/text from the Caller ID event... but the event is delayed about a full second after the incoming call state change. So the phone rings for about a second before I display Caller ID.
  • When in a call already, and a second call comes in (Call Waiting), the Caller ID event actually happens BEFORE the call status event indicates there is a call waiting... and the Caller ID event only provides the phone number!

This actually stopped me from creating a videos showing off Call Waiting behavior, because I didn't want to expose any of my family members' phone numbers, and I didn't want to deal with blurring the numbers in the video. It also is lame that I can get a name for a normal incoming call, but not for a call waiting.

After some time on Google, I learned about an "AT" command supported over Bluetooth HFP to request details about all current calls: "AT+CLCC"

For each call, it indicates (among other things) whether it is active, on hold, pending incoming, pending outgoing, etc., as well as the phone number and the "name" associated with the call. Search this page for "+CLCC" to find all the details. Strangely, I can't seem to find any definitive documentation about HFP AT commands. Instead, I seem to find documentation of AT commands supported by specific implementations of modems, etc. (UPDATE: I found the official Bluetooth HFP 1.7 specification, which details the HFP-specific AT commands, but defers to other standard for details of some commands).

So now whenever I get an incoming call or an incoming call waiting, I send the "AT+CLCC" command and scan the responses looking for a call whose status is 3 (alerting) or 5 (waiting), and parse out the name and phone number. If there's a name, I use it for Caller ID, otherwise I use the number.

This response comes in very quickly, so I can display Caller ID practically immediately when the phone starts ringing. I also get a name for call waiting calls. Here's an example of logging when placing an outgoing call, then receiving an incoming call waiting:

call_waiting_logging.PNG


I'm pretty sure this is the same information the Bluetooth module is using to implement its Caller ID event. I haven't been able to find any info about any other HFP commands/events that could provide such info. So in this case, the strange behavior of the Caller ID event is probably a bug in the Bluetooth module's firmware, rather than a bug in my phone's HFP support.
 
Last edited:

Latest threads

New Articles From Microcontroller Tips

Back
Top