Sunday 19 October 2014

New dialler code

This is the schematic for the dialler to GMS module.

Below is a representation of a dialled number:

---------------_-_-_-_------------_-_-_-_-_-_----------

would be "35". The long pulse as the rotary is rotated anti-clockwise then the pulses for the number as the rotary returns. So when a long pulse is received, the previous set of pulses has finished and the count of these pulses is saved as the number.

The code is much simpler: (Note to self: this is in a file called push_button.c for some strange reason!)

void getNumber() {
   int16 x = 0;  // number lemgth
   int16 count = 0; // button press count
   int16 pulseCount = 0; // counts the pulses from the rotary
   int32 timer; // This is the timer
   BYTE status; // This if for detecting button state
   char phoneNum[15] = ""; // A character array for the phone number
   char num[4] = "ATD"; // start of the dial string
   strcat(phoneNum,num); // cp the start of the dial string to the phone num AT command


    // do this while the phone is still off the hook
    while (!input(PIN_A1)) {

      if (input (PIN_A0)) // dialer input high
      {
         delay_ms(10); // debounce
         pulseCount++; // This counts the number of clock cycles
         status=0;
         timer=0;
      }

      if (!input (PIN_A0) && status == 0 ) // dialer input low
      {
         delay_ms(10); // debounce switch
         if(pulseCount > 20 && count>0) { // add the count to the AT string
            count--; // decrement as the number is always one more
            if(count > 9)
               count=0;
            sprintf(num,"%ld",count); // makes int count into a string
            strcat(phoneNum,num); // adds num to the phoneNumber
            count=0; // reset the number count
            x++;
         } else {
            count++; // increment the number count
            status=1;
         }
         pulseCount=0;
      }


      // long delay before writing the AT command to GSM
      if( timer > 150000 && x > 0 ) {
         // add the final number
         count--;
         if(count > 9) // if the pulse count is 10 then this is actually a zero
            count=0;
         sprintf(num,"%ld",count); // makes int count into a string
         strcat(phoneNum,num); // adds num to the phoneNumber
         timer=0;
         x=0;     // reset number count
         count=0; // reset pulse count
         printf("%s;\r",phoneNum); // This is the AT command sent to the phone
         while(!input(PIN_A1)); // wait for on hook.
         return;

      }
      timer++;
   }

Saturday 18 October 2014

Phone call placed with PIC!

I have done the first end-to-end demonstration of dialling a number with the rotary dialler and placing a call using the Seimens T30 phone module via a MAX232.

The only problem I had was that I'd bought a passthrough RS232 cable instead of a cross over (aka "null modem cable". This basically makes the output of the RS232 the input to the phone by crossing over the Rx & Tx.

I achieved this by stuffing some wires in until I get my new X-over cable.


Next step is to improve the dialling detection. Currently I am waiting about 1 second after the last received pulse to determine the end of the dial to add the number to the AT string. At the beginning of the dial there is a long pulse as you rotate the rotary anti-clockwise, I will try and use this to indicate the the previous number has been dialled.

Sunday 12 October 2014

Dialler working...


The dialler now works, I have hooked up the rotary dial unit from the GPO phone to the circuit and all numbers are decoded correctly (most of the time) and sent to the RS232 port.




I am waiting for a RS232 - RS232 cable to send the AT command straight to the GSM module.

I had problems with switch bounce from the rotary, but this is almost eliminated with the introduction of 10ms delays after the port on the PIC is read.



The code so far:

#include "C:\Users\Daddy\Documents\CCS\push_button.h"
#include <stdio.h>
#use delay(clock=8000000) // 8MHz
#use rs232(baud=9600, xmit=PIN_B7, rcv=PIN_B5,bits=8)


void getNumber();
void checkOnHook(void);

void main(void)
{
   printf("::main()\n\r");

   // set stuff up
   setup_adc_ports (NO_ANALOGS|VSS_VDD);
   setup_adc (ADC_OFF);
   setup_spi (FALSE);
   setup_oscillator(OSC_8MHz);

   // This is the main loop
   while(true) {
      checkOnHook(); // this will wait for an incomming call
      getNumber(); // gets number from rotary and sends AT command
   }
}

// Checks if the phone is on the hook via A1
void checkOnHook(void) {
   BYTE flag=0;
   printf("::checkOnHook()\n\r");
   // RA1 the ON/OFF Hook detection
   while(input(PIN_A1)){
   // waiting for an incoming call
      if(flag==0) {
         printf("waiting for an incomming call!\n\r");
         flag=1;
      }
   }
   return;
}

// This function returns a char array that is the AT command
void getNumber() {
   int16 x = 0;
   int16 count = 0; // button press count
   int32 timer; // This is the timer
   BYTE status; // This if for detecting button state
   char phoneNum[15] = ""; // A character array for the phone number
   char num[3] = "AT"; // start of the dial string
   strcat(phoneNum,num); // cp the start of the dial string to the phone num AT command
   printf("::getNumber\n\r");

   // do this while the phone is still off the hook
   while (!input(PIN_A1)) {

      if (!input (PIN_A0) && status == 0) //input button
      {
         status = 1;
         delay_ms (10);
         output_low(PIN_C3);
         count++;      }

      if (input (PIN_A0))
      {
         delay_ms(10); // debounce?
         output_high(PIN_C3);
         status = 0;
         timer = 0; //reset timer after a pulse has been received
       }
      // short delay for individual numbers
      if (timer > 40000 && count > 0)
      {

         x++; // increment the index by one
         count--;
         if(count > 9)
            count=0;
         sprintf(num,"%ld",count); // makes count into a string
         printf("count = %ld, %s\n\r",count,num);
         strcat(phoneNum,num); // adds num to the phoneNumber
         printf(">%s\n\r",phoneNum);
         timer = 0;
         count = 0; // reset the counter
      }
      // long delay before returning the AT command
      if( timer > 100000 && x > 0 ) {
         timer=0;
         x=0;
         count=0;
         printf("%s;\n\r",phoneNum);
         while(!input(PIN_A1)); // wait for on hook.
         return;

      }
      timer++;
   }

}

Saturday 11 October 2014

Starting again....

From now on all posts are for the new and improved version of the retro-mobile.

The software will be on a PIC microcontroller - they are obviously much smaller than a Raspberry Pi and use a lot less power! I am using the PIC16F690 coz this is the one on the "low pin count" demo board that comes with the PICkit2 programmer. The plan is to use the PIC16F913 as this has LCD driver capabilities.

The basic functionality will be the same:

  • Receive call from GSM module
  • Decode and dial number from rotary dial
  • Place call with AT command on GSM module.

I have made a start by buying a new GPO phone:


...and a GSM module...

This will be incorporated with the new ringer module - yet to be built. The original mic/speaker will be replaced with some more modern 8ohm ones - should give a clear sound.

I've also completed the C code to decode the dialling and produce the AT command. I've been testing this with an RS232 to USB cable into my Win7 laptop using RealTerm. The AT command is just the unaltered output from the PIC16F690's UART TX PIN. When I was researching this I was under the impression that I needed a MAX232 to produce a text string that could be read by RS232.

I haven't tried to simulate any RS232 input to the PIC yet - this may require a MAX232 - one on order just in case!

C code to follow - it's not as nice as Python (or Java!)