Close
0%
0%

DIAVOX Cellphone

Turning an old diavox phone into a cellphone. No smart stuff, just a telephone. Pick up the handset and dial just like the old days.

Similar projects worth following
I remember the days when a phone was just a phone. Pick up the handset dial the number, just you the phone and the other person you are talking to. Place the handset back on and the call ends. No fancy smart features to distract you. This project is about turning an old telephone into a portable cellphone and learning new things on the way.

The Diavox Project "Old phone cellphone"

Where to start?

The scope of the project is rather large so it is divided into sub-projects and their individual tasks. Some have dependencies which have to be completed first.

Sub-projectStatus
Debug probeCompleted  
Rust programming toolchainCompleted  
Bell ringerUnderway
Keypad matrix scanningAlmost finished
DTMF keytone generationGetting there
Codec breakout PCBStarted
LTE ModemNot Started
Connecting everything togetherNot Started
Power supplyNot Started
ProgrammmingStarted
Read more »

  • PWM audio and High-speed I2C

    Anders Helgesson02/10/2025 at 21:13 0 comments

    I've changed my mind about using PWM audio, since I already have the DAC set up I'm going to try to use PIO to get a high-speed I2C interface for the DAC. I found two interesting PIO I2C implementations the pio-i2c-hs which is a High-speed I2C PIO implementation in C and the i2c-pio crate which implements the I2C hal using the RP2040 PIO peripheral.

    Since the rust implmentation lacks documentation and examples how to use it. I'm not even sure if it can be set to use high-speed I2C. I'm going to use the PIO program from pio-i2c-hs and port the C code.

    In the documentation for the pio-i2c-hs it mentions that to reduce jitter the rp2040 should be clocked at a multiple of 8*3.4 MHz = 27.2 MHz, and suggests to set the clock at 136000. I'm going to set it to 108800 underclocking the rp2040 instead. I have no heavy stuff going on so it should be fine.

    I'm guessing that porting this to rust, the best way would be to make a new crate, then I could share it, and even use it for other projects.
    I have no idea how to do that, how write tests and so on. It's a new Learning opportunity! The PIO program itself would be licensed under BSD-3 clause, I guess the rest of the rust code I could MIT license.

    I have 4 free pins if I look at my pinout in the project treesheet.

    Not sure if I need all the ones assigned to the modem so I'll use the first 2 pins I guess.

    Now this is probably going to take some time but It's probably worth it. I could always fallback to PWM audio, SPI DAC or a wild thought, use PIO to SPWM two tones and mix these to make a DTMF tone.

  • LLM's are useful but sometimes not so

    Anders Helgesson02/08/2025 at 20:48 0 comments

    ChatGPT

    I've been using ChatGPT plus for sometime but I realized that, asking it for solutions for problems actually invites you on a wild goose chase or direct you in the wrong direction some times.

    Maybe I'm not being precise enough in my requests or asking the wrong questions. I've cancelled my subscription as I'm going to use it less from now on. Time can be saved though with LLM's so they really have their uses.

    I'll use it to study and ask about concepts instead and If I'm really stuck I might ask for a solution.

    Bing

    I tried using microsoft bing once, and when I jokingly asked if they use bing's brother, bong internally at microsoft it just wouldn't answer and then acted like I never asked the question in the first place.

    I told it to print out my requests which it did excluding my joke. When I said one request was missing, it simply added a random made up one. When I said I never asked that question, it said that it must be from another conversation.

    Previously I had asked bing about things like that and it said that there is no link between users requests, between conversations and so on. I pointed that out and then it said that that it is correct. Then it said it didn't know why it happened.

    Manipulative LLM's?

    If a LLM is trained so, it can lie and probably does so, they can twist and direct the user into another way of thinking. Users should be wary of this as it could be very subtle. It's another reason why I've decided to cancel my subscription, OpenAI they call themselves, say where is the Open part? I guess anyone can use it and perhaps become manipulated?

    Others ones like Bing or Deepseek for example is no better I guess. If the new generation are not teached properly about these new tools, the internet, the media and their dangers and uses. I guess this quote from Einstein sums it up. 

    "I fear the day that technology will surpass our human interaction. The world will have a generation of idiots." - Albert Einstein

    I think LLM's are really cool and useful but who decides what information is good for the user? Isn't that up to the user to decide themselves?

    Excuse me for my rant, time to get back to the project.

  • Timer based playback

    Anders Helgesson02/06/2025 at 20:41 0 comments

    I'm going to try to implement a timer which is going to be used to control the playback at 8kHz. The timer ISR will send data to the I2C every 125 micro second to keep the 8kHz playback rate.

    I'm going to use a global buffer that can be set and you start and stop the timer to play it back. I should probably have some functionality to reset the playback to the start of the buffer as well.

    I used ChatGPT to make a python2 script to generate the DTMF tones using the lesser common multiple of each pair. This time, time was actually saved! The largest DTMF tone is the 1 button with 84 samples at 8kHz.

    I've made the buffer it can hold 1024 samples, I should probably make it smaller later if I don't need that size.

    Vimeo Video

    It sounds horrible!

    Bring out the oscilloscope!

    The signal looks okay.

    It seems like the delay is at 210 micro seconds instead of 125. 210 - 125 = 85 micro seconds. The overhead of the code is 85 micro seconds, I would need to remove that from the delay. 125 - 85 = 40 micro seconds. I'll set it to 40 micro seconds.

    Spot on! Sounds a bit better.

    Vimeo Video

    I guess I'm into the limitations of the sample rate at 8kHz and the filter at this point. Some of the tones only have a few samples. A higher sample rate is possible if I use PIO to send the DATA to the DAC using high-speed mode at 3.4 MHz. It's tempting to just learn how to use the PIO, perhaps for another project.

    Well that concludes my I2C DAC adventure. I've learned about various things in both hardware and software. It's time to move to PWM audio instead.

  • Op-amp troubleshooting

    Anders Helgesson02/03/2025 at 20:19 0 comments

    This is what the waveform looks like from the DAC with 3.3 volts this time.

    Looks good

    This is what it looks like after the LPF(Low pass filter).

    The waveform is cleaned up but it also drops in voltage, it's because of the voltage divider at the op-amp input.


    This is what it looks like after the pre-amp stage.

    It's still being clipped...
    This is what it looks like after the buffer.

    Same, this is to be expected
    This is what the output looks like after the amplifer.

    Okay..., the amplifer is powered from USB so that's probably where the noise comes from. I'll pretend I didn't see that and move on.

    Okay, I'll remove the lowpass filter for now and the voltage divider at the pre-amp input. Now it looks like this.

    Most of the time I don't know what I'm doing it seems that I'm trying to amplify a signal that doesn't need to be amplified... Stupid me... The DAC is already outputting at 3.3 volt. I do not need to amplify the signal further I could just use the buffer directly instead. 

    I removed the Pre-amp and put the filter back instead so now it's like this DAC -> LPF -> Buffer -> Amplifier -> Speaker.

    The signal after the Buffer now looks like this.

    It sounds much much better. According to the oscilloscope I'm getting a 392.2Hz signal instead of the 400Hz I want. I need a better timer to handle the 8kHz playback.

    Here is some pictures what the breadboard setup looks like.

    Today I took a different approach to writing the log, instead of writing a log entry at the end of the session, I updated the log entry as I went on. This seems to be better and also gives a bit of reflection what I'm doing. I'll probably continue doing this.

  • Solved the LDO problem

    Anders Helgesson02/02/2025 at 21:44 0 comments

    This morning I soldered two new 3.3 volt LDO modules.

    Plugged one in and I got the same result! 2.4Volts! Why?

    Actually before I snapped the LDO module pcb it was working perfectly fine, the main problem was I were feeding it 3.3 Volts instead of 5 Volts. With the voltage drop you can never reach a 3.3 Volt output with a 3.3 Volt input... Stupid me. Anyway with that mistake cleared up, I can continue.

    I plugged the LDO correctly to VUSB so it gets enough voltage to work properly now I should get a tone with 397Hz but I don't. Looking at the measurement after the pre-amp in the last log, it's clearly clipping the waveform at the pre-amp stage.

    Back to basics again. To be brutally honest, I don't even know, how and why op-amps work. After clearing up some of the op-amp basics, I noticed I had the gain set at 2.8 instead of 2. So I replaced the 18k gain resistor with a 10k resistor and now it sounds better but not quite right.

    I have to look at the waveform with my oscilloscope, but the project time has run out. So that will have to wait until tomorrow morning.

  • There is sound...

    Anders Helgesson02/01/2025 at 23:34 0 comments

    This took longer than expected due to my knowledge gap in digital audio, misconceptions about stuff in general, and of course lack of time. I failed more times than I can count but I managed to figure it out, mostly.

    So I had the assumption that I2C at 400khz should be able to playback clean simple tones easily, this was not correct including the communication overhead the practical achieveable sample rate is only 8khz. There is another problem, the DTMF which are two tones combined. You can have a LUT which has combined the two tones but it will not cleanly loop. I would need multiple cycles of each waveform until it both tones loop at the same time. You could also have two seperate luts for each tone and combining them before playback.

     Looking at the LUT below, the DAC's 12bit resolution is not very usable at low sample rates.

    pub const TONE_1633_HZ: [u16; 4] = [
        2047, 4009, 3162, 718
    ];

    Only 4 samples for the 1633 Hz tone... It's not going to sound very nice.

    I decided to use the Japanese dial tone at 400 Hz for testing. So I made a LUT at 8khz sample rate, it's only 20 samples.

    pub const TONE_400_HZ: [u16; 20] = [
        2047, 2679, 3250, 3703, 3993, 4094, 3993, 3703, 3250, 2679, 2046, 1414, 843, 390, 100, 0, 100, 390, 843, 1414
    ];

    I used the oscilloscope to measure the delay and adjusted it as close as possible to get 8khz playback. I get 397 Hz. But it doesn't sound like a sinewave for some reason. So I added a lowpass filter, since I lack a stock of various components I used two 10k resistors in parallel and a 0.01uf cap for the filter. Still doesn't sound like a sinewave.

    The signal looks like this from the DAC.

    So I measured the signal before sending it to the pre-amp and then it looks like this, the filter does it's job.

    The signal looks fine. Now measuring it after the pre-amp it looks like this. Now I guess I've connected something wrong to get this result.

    The voltage looks lower than it should be so I measured the output from the LDO and its only 2.4 volts and 2.7 volts at no load. I seemed to have damaged the LDO module while soldering or something, the pins and a piece of circuit board came off when I pulled on them. I've decided to solder a new LDO module. I'll put the broken one in the various parts bin, I could probably salvage the LDO when I get SMT tools.

    When I get tone to output cleanly, I will rewrite it so the playback buffer is played using a timer instead, so I can get accurate 8khz playback. My current delay is not accurate enough.

    Once I get this to work with the I2C DAC, I'm going to switch to PWM audio instead. This would give me a much higher sample rate with less components.

    There is a way to use the I2C DAC at a higher sample rate, using high speed I2C at 3.4Mhz. This is not possible with the I2C inside the rp2040 as it only goes to 400khz, you would have to use PIO to send the data instead. Fast mode plus at 1mhz is supported in the rp2040 but that doesn't work with the MCP4726. I'm probably going to try PWM audio first, for learning it might be worth exploring the PIO approach though.

    I'll try to write a log after each session but it's difficult since I always go overtime. I tend to get into the 'zone' and forget about everything else. Not very professional...

  • ISR and DAC

    Anders Helgesson01/23/2025 at 04:39 0 comments

    I have implemented the ISR for the GPIO pins I want to use, keypad works perfectly but there is no debouncing on the reset/handset switch. This triggers the ISR multiple times for the different pins when the switch is quickly actuated.

    That's not good and debouncing has to be added. There is probably a few different ways to do it. I decided to go with hardware debouncing of the switches. I used a 10k resistor and a 4.7uF capacitor for each switch. With the debouncing in place, the ISR acts like it should.

    The handset input pin triggers the ISR on high edge, which is when the handset is removed.The reset input pin triggers the ISR on high edge, which is when the reset switch is engaged. Switches to the reset state and when it finishes it will poll the reset/handset switch, to tell if the handset is on or the reset has been released.

    I've implemented the state switching. It does switch to the correct states without problems. While working with the keypad state switching, I had a problem with the keypad scanning for some reason. I figured that out, the R key seems to have traces connecting to the keypad matrix, which messes up the keypad scanning. I disconnected the real R key for now and connected the orange push button again.

    I've implemented a function to play tones and I get tones out of the speaker but it sounds all messed up. Looking at the dac output in the oscilloscope it doesn't look like a 12bit signal more like a 4 bit one. I seemed to have missed to send 4 bits of the data.
    The MCP4726 wants the first byte to have 2 command bits, 2 power down bits, 4 data bits, and The second byte is all data. I rewrote the code but I haven't tested it on the hardware yet.

  • IRQ and programming

    Anders Helgesson01/19/2025 at 22:39 0 comments

    I've decided to implement GPIO IRQ for the handset switch pin, reset pin, and keypad active pin. Using the GPIO ISR to switch states makes everything a bit easier.

    I measured the reset/handset switch and mapped how it works. It has 8 pins and you can use some of the pins differently depending on the type of switching action you want. From what I could tell only 6 pins are used.
    For the handset, use the pins that close the switch when the handset is off.
    For the reset, use the pins that close the switch from reset to handset on.

    I've disconnected the toggle switch and connected the handset switch instead. I've disconnected the push button and connected the R button. I will use the push button to simulate a URC from the modem later.

    I checked all the connections and powered the breadboard up. There is humming on the DTMF audio output, I have no decoupling capacitors or LDO. Putting my finger on the MCP6002 increases the humming. :)

    I'm working on making the interrupts work but just when you get into 'the zone', time's up...

  • Parts, soldering and programming

    Anders Helgesson01/17/2025 at 20:41 0 comments

    The parts have arrived!

    Yesterday morning, I soldered the pins to the components I'm going to use. I also soldered a PML capacitor between two pins to use for coupling. In my haste, I soldered the PAM module upside down. :D Doesn't matter much, except that the silkscreen and components are now on the bottom. Stupid me. Not having a workstation to solder at makes it a bit time-consuming, as I have to set everything up, solder, clean up, remove all the tools, and store them. The project and all my tools live in boxes and they have to go back into the closet before I go to work.

    I've connected everything, I've not used a separate LDO for audio, so there might be some noise. I have to double check all connections before powering it up.

    This morning I did some programming. I've added LUTs for the DTMF tones but I also need to add a LUT for the dialing tone. I've added a function that plays DTMF tones.

    The dialing tone will be played when waiting for input. There is a small delay needed to maintain the sample rate, this might cause issues with user input. I might need to add the check for the key pressed signal inside the loop which sends the values to the DAC.
    Perhaps an ISR might be the way to go for the key pressed signal, enabled only when the handset is off. Then I wouldn't need to worry about it as the ISR would switch states to the key_pressed state.

    Looking at everything it has become clear that for the final version I need a custom mainboard. Gluing all these modules inside would probably be a disaster if I want to use it daily. It's something I'll worry about when the prototype is completed.

  • DTMF tones and states

    Anders Helgesson01/15/2025 at 10:10 3 comments

    It's been a week, and I've spent time on the project now and then.

    With the keypad working, I need to output the dialing tones and DTMF tones for each digit pressed as a line level signal. I want the tones play when testing the keypad matrix further.

    I've never worked with audio stuff at component level before so this is a great opportunity for learning. I've decided to use a 12-bit DAC to output the tones to an Op-amp as Pre-amp and Buffer which should then be fed into the codec AUX input. For testing I'm going to feed the signal to an amplifier connected to a small breadboard speaker. I was missing some components so I have ordered them.

    While waiting for more components, I continued to work on the software side. I need to store the data for each tone in lookup tables so the CPU doesn't need to calculate them at run time.

    I've also decided to add another state, a key pressed state. The code will enter this state when a key is pressed on the keypad, check which key is pressed and output the DTMF tone until the key is released. When you release the key, it will store the key pressed in a vector, keeping track of the digits pressed. It will then transition back into the dialing state. This time the dialing input timer is started and the dial tone is turned off. If the timer expires the code will transition into the calling state, where it will try to call the entered number.

    I think I need a new state for when the recipient hangs up. It should play the tone to indicate this.

    If you leave the handset off for some time, it will play the handset off alert tones and, if there is no input for a set time, go to sleep. Can I have the modem register the phone as busy, while it self goes to sleep? Handset off = no calls :)
    Should the phone be set as busy? It might be better not to have it as busy? Would the caller keep trying, thinking that the phone is in use? What settings can be done in the modem?

    What other tones might I need? Perhaps if you try to make a call without reception? Low battery?

    Holding down the R key while lifting the handset, should it be put into speed dial mode?

    Holding down the R key during the dialing or active call goes into command mode, where you can adjust the volume and other settings using the keypad.

    I also need to check for the reset switch, if activated it should return to dialing state with a clean slate.

View all 46 project logs

Enjoy this project?

Share

Discussions

Ken Yap wrote 01/08/2025 at 00:41 point

Interesting idea. Is the DTMF tone generation to make it sound like the old days? AFAIK that's not how numbers are "dialed" with mobile phones. Although some automated response systems will want DTMF tones during a call for responses.

Also speed dial storage could be considered. Punching 10+ digit numbers for frequently called people will get old.

  Are you sure? yes | no

Anders Helgesson wrote 01/08/2025 at 09:21 point

The DTMF tones are just for aesthetics, and their whole purpose is for the user to hear the keypad tones. If I understand the codec datasheet correctly, I can route the tones (via AUX) so the recipient can hear them as well, but I will probably not do that. 

Dialing and pressed keys during a call, they will be sent to the modem over UART to be handled.

I will probably add speed dial features once the phone is working.

  Are you sure? yes | no

Giulio Pons wrote 01/06/2025 at 00:03 point

Very nice! Do you use a SIM card to make the phone call?

  Are you sure? yes | no

Anders Helgesson wrote 01/06/2025 at 21:31 point

Yes. I'm planning to use a Quectel EG25-G, 4G LTE modem to make the phone calls.

  Are you sure? yes | no

Does this project spark your interest?

Become a member to follow this project and never miss any updates