BASIC Stamp modem

(c) 1998, 2003 EME Systems, Berkeley CA U.S.A.
<stamp index> <home>

Contents: (updated 2/7/2003)



Modem

top

Modems usually are destined for remote sites where you don't want any glitches or difficulties. Here are a few tricks that help make the BS2 system with a modem reliable and user-friendly. With a modem, you should never trust that the connection is going to go by the book. If anything can go wrong, sooner or later, it certainly will.

It pays to have a technical manual for the modem you are using. Modems vary widely in the commands they support ,and the default values for the parameters. True, you can discover those things by trial and error, but who needs it?

If you want to use the "system" port (pins 1 & 2) on the BS2 for a modem, the trick is to preinitialize the modem (by sending the "E0" command from a regular PC, see below) so that it does not echo commands. Both the BS2 system port and the modem normally echo the characters they receive, so the first command sent from the BS2 to the modem will lock your system up in infinite reverb, unless the echo is turned off.

The concern in the previous paragraph does not apply if the data lines to the modem will be connected to one of regular stamp pins, P0 to P15. Those pins do not echo.

You should find a modem that allows you to store a power-up configuration in its eeprom. This is essential if you plan to use the system serial port on BS2 pins 1 and 2. Some cheaper modems do not implement the configuration storage feature. The configuration memory in the modem can relieve the BS2 from having to do the configuration each time at power up. The configuration memory can also store phone numbers for automatic dialling.

There are some commands that you will want to store in this non-volatile memory in the modem. That way you can be sure the modem is always initialized in the way that works with your BS2 system. I suggest the following command string:

  AT &F E0 Q1 S0=1 &C1 &D3 &W0 &Y0 ^M
      where
  &F    brings in the factory defaults
  E0    turns off command echo 
  Q1    turns off result reporting
  S0=1  to autoanswer on the first ring
  &C1   enable DCD pin to follow actual carrier status (see below)
  &D3   enable hardware reset via DTR drop (see below)
  &W0   stores the configuration in eeprom set #0
  &Y0   chooses eeprom set #0 as the power-up default. 

Some modems don't support &Yn command and always use set #0 at powerup.

Result codes are a problem in systems that are set up to auto-answer incoming calls, when using the system port on BS2 pins 1 and 2. On many modems, the echo of the "RING" result code prevents the incoming call from connecting. This is less of a problem on the regular BS2 pins. Any data received from the BS2 during a connection attempt will usually abort the connection.

Use the S0=1 or S0=2 command if you want the modem to answer the call on the first or second ring. Use S0=0 if the BS2 will originate the calls (no autoanswer).

If the BS2 will originate calls, you may also want to use the modem's capability to store a phone numbers in its memory. The numbers are usually stored with the "Zn" command.

The options for the &C1 and &D3 are discussed in more detail below in connection with the hardware installation.

IMPORTANT: If command echo and result codes are disabled, be sure to attach an advisory note to the modem to that effect. The note should tell the curious to issue the following command:

   AT &F &W0 ^M

which resets the modem to its factory defaults. Otherwise someone at a future date will think the modem is busted.

Unless you really want to get in deep, you may want to turn off the advanced features of data compression and error correction (if it supports them to begin with). The commands to turn off these features are

    \N0         turns off error checking
    %C0         turns off data compression

Include these in the above string. Be sure to include this in the initialization of the modems on both ends of the communications. In hyperterminal on the PC, this command can be entered in
properties/connect to/configure/advanced-extra settings=\N0%C0

Here is another command supported by some modems:

    S37=6       fixes the first-try baud rate to 2400

This fixes the baud rate at 2400. In hyperterminal, you can enter this in the setup:
properties/connect-to/configure/general="2400baud"+"connect only at this speed".

Use the appropriate value for the connection speed you want to establish. By fixing this value, the modems will negotiate the connection more quickly and reliably than if they have to seek out the common ground. Issue the same commands both to the modem attached to the BS2 and to the modem at the other end of the connection. Quite often older modems are blown away by the bizarre sounds coming from an advanced modem. Do all that you can to match the settings at both ends from the outset.

I usually use the DCD (data carrier detect) line to signal to the BS2 that the modem is on line and ready to talk. The DCD line goes high when the modem detects a carrier (when &C1 is set). The DCD line can either go into a regular BS2 pin, to be detected by polling, and/or it can go via a capacitor into the ATN input, to wake up the BS2 for immediate action. I put in both options, so that the program can test the DCD line to help determine the cause of the reset, and branch to the modem routine if appropriate. The RD (ring detect) line from the modem can be added into the mix to give advance warning that the modem is going to be attempting a connection.

It is important not to send anything out through the modem port while the modem is negotiating a connection. Many modems, if they receive characters from the BS2 before the connection is established will instantly abort and hang up. Your program must be designed not to send characters to the serial port except when DCD is high..

The DCD line goes from high to low when the modem loses its carrier. The setting in the S10 modem register determines how long after loss of carrier it is before the DCD line goes back low.

Some modems stay on line, receiving noise, even if they lose the carrier. What are the consequences of that? Suppose the BS2 SERIN command will receive one or more bytes. The serin command will probably have a timeout associated with it, so that if it does not receive datawithin a period of time, it will branch to a special routine to handle the timeout. However, this is far from foolproof with a modem involved. If the modem loses carrier, but still remains connected to the line, then noise from the line can generates random data. It can fool the serin command, so that it never branches to its timeout routine. Any bit of noise is enough to send the serin timer back to the beginning. The upshot is that the system needs a way to reset the BS2 in case anything becomes stuck. One way to do this is to have the DCD line reset the processor when it goes from high (online) to low (offline).

One option for hanging up the modem under software control is the +++ ATH0 command. However, that sequence is never a sure thing. The sequence can be corrupted by noise, and sometimes the modem does not "hear" the +++ escape sequence. There is a much more reliable way to reset the modem, via hardware and the DTR line. The DTR line is an input to the modem, and so long as it is kept high, the modem will stay connected. But when the DTR line is brought from high to low, the modem hangs up, resets and executes the initialization commands. That is what happens if the &D3 option is set. There are other options for handling the DTR line, but &D3 option is the most reliable. Hardware reset option is by far the most reliable to guarantee that the modem will be left in a state ready for the next call.

Here is one simple approach to the hardware, with the above considerations in mind:

   DTR-----/\/\-------;
        |  100        |
        |             |
       _V_ 4148       |
        |             |
   DCD--;---/\/\---;--'-;--------P15
        |  10k     |    |
        |         ---   \
       ---     5vz ^    /
       ---         |    \ 100k
        |          |    /
        |          |    |
       ATN        com  com

When DCD goes high, it resets the BS2 via the ATN line. After reset, P15 is an input, and the BS2 can test P15 to see if the modem is active. The pin reads HIGH if the modem is locked on to a carrier. If so, the BS2 goes into a modem user interface routine. This can be designed either for an automated exchange or for a human operator. When it is time to hang up the modem, the BS2 brings line P15 active low, to bring DTR low to hang up and reset the modem. The DTR line is connected both to the P15 pin of the stamp and through a diode to the modem's own DCD line. If the carrier is lost inadvertently, the modem will hang-up and reset. Note that the DCD line does not reset the processor when the carrier is lost. If the carrier is lost inadvertently, then the modem should hang itself up (quenching noise on the received data line) and the timeout on the serin command should kick in to put the BS2 back in operation.

Another consideration is what will happen with remote commands that cause the the BS2 to go off and do something, such as transmitting back real time data. What if the operator on the other end needs to interrupt the process to return to a main menu? This is not a problem if every command evokes a short quick response. One way to implement a quick response is to add a provision to detect the BREAK condition on the serial line. Normally the RS232 serial line is in a marking (negative voltage) state, and the line pulses positive only briefly to transmit data. A BREAK signal is an intentional positive level for about 0.3 seconds or more. Most PC telecom programs are able to generate a BREAK condition on the serial line. A stamp program can test an input pin on a time scale of 0.2 seconds or less and respond if the BREAK condition is detected. Alternatively, external hardware can detect the break and reset the stamp, like an interrupt. Here is a simple circuit to add break detection by polling:

   Rd line in from modem --/\/\----P14
                           47k

One more caveat. In some cases where there is heavy danger from lighning, it may be desireable to detach the whole modem circuit from the telephone line via a high-isolation relay, except when a call needs to be made. Or, depend good zap protection and good grounding.



Modem supervisor, using an auxiliary BS1

top

There is often need to operate a modem off of battery power. In most of the sites where I want to put remote modems, such as out on farms or at field stations, the 120 volt electrical power is unreliable or nonexistent. Moreover, it is precisely at the times when the power fails that I need most to monitor the conditions via the modem. There are not many modems available that are designed specifically to operate from battery power. The Cermetek modem module that can be easily adapted. The BS2 can control the power to the modem via a transistor switch, and turn the modem on only when needed. The industrial Cermetek CH1786 has a ring detect circuit that is active even when the modem power is off, and that is used to trigger the full application of power to the modem when a ring is detected.

Here is the circuit, using a BS1 (or the "burned" equivalent) as a supervisor:

modem supervisor circuitCermetek CH1786 modem

The modem itself is initialized as described in the preceding article, or as appropriate for the situation.

When the BS1 detects the ring on the phone line

  • it turns on the power to the modem and allows the modem to connect, which is indicated by an active DCD line.
  • if the modem does not connect in a reasonable time, and the ring stops, the BS1 turns off the power and goes back into waiting mode.
  • Once successfully connected, the BS1 generates a high pulse on the ATN line. Usually on my systems that does in fact go to the ATN input on the Stamp and causes a reset . The Stamp then can exchange information over the modem channel. The ATN signal can also go to a regular BS2 pin for detection by polling.

While the call is connected, the BS1monitors the line for activity.

  • If a BREAK signal comes in over the phone line, the BS1 detects this and again resets the Stamp. That allows the remote modem to regain control in the middle of long procedures.
  • The BS1 monitors the DCD line, and if the carrier is dropped, the BS1 does a hardware reset of the modem through the DTR line, which causes the modem to hang up, and then the BS1 turns off the modem power, sends another reset pulse to the Stamp, and then goes back into its sleep mode, awaiting a new ring signal to arrive.
  • If a long period of time passes with no activity on the rxd and txd lines, the BS1 intiates a hangup and powerdown.
  • While connected, once communication starts, the ATN line becomes an input, and the modem stays connected so long as that line stays high. If it goes low, being forced low by the Stamp, the BS1 interprets that as a hangup command. It hangs up the modem, resets the Stamp with a short active high pulse on ATN, and goes back into its waiting mode.

In the waiting mode, the BS1 sleeps, and wakes up once every second briefly to check the state of the RI line, and if no ring signal is present it goes back to sleep. There is a slow RC circuit on the above circuit on the RI pin, to stretch the short ring pulses to give the Stamp time to detect them. If RI stays high, as a test mode that can be pin strapped from outside, the BS1 will hold the modem power on.

Also in the waiting mode, the BS1 can check the ATN input, and if that input goes low, the BS1 can apply power to the modem and allow the BS2 system to originate a call.

The actual data passes straight through between the modem and the main BASIC Stamp II. The BS1 does not act as a buffer for the data itself. It is only a supervisor.

Here for reference is the BS1 program. (originate option not shown).

' autoanswer modem routine for BS1
' as a dedicated modem supervisor for a master BS2.
' (C) 2001 Tracy Allen, eme systems
' mailto:tracy@emesys.com
   ' http://www.emesystems.com
   ' http://www.cermetek.com/
   ' Cermetek CH1786 initialization:
' AT&F^M
' AT S0=1 E0 Q1 &C1 &D3 ^M
' initialize at 2400 baud
' answer 1st ring
' no echo, no result codes
' dcd follows carrier (low when carrier detected)
' dtr HI hangs up and resets modem
' atn line is output to reset the Stamp
' same line is input to monitor stamp for activity
' rx line is monitored for the BREAK condition
symbol  rxd=pin0    ' normally high marking
symbol  txd=pin1    ' normally high marking
symbol  dtr=2       ' bringing DTR low will reset the modem
symbol  ri=pin3     ' ring detect will pull low when phone rings OC
symbol  rip=3       ' ring detect pin
symbol  dcd=pin4    ' goes low when carrier is detected
symbol  ati=pin5    ' ATN as input
symbol  atn=5       ' will go high to wake and signal the OWL
symbol  led=6       ' high flashes led on
symbol  lep=pin6    ' also for led
symbol  pwr=7       ' high turns on power
   
symbol  rxd0=bit0   ' NOT rxd
symbol  ati0=bit1   ' NOT ati
symbol  cnt1=w1     ' counter for inactivity watchdog
            ' also counter to wait for carrier
symbol  cnt2=w2     ' counter for time ati low-CPU hang-up
symbol  cnt3=w3     ' counter for BREAK on rx line
   
'test:
'  dirs=%11111111
'  cnt2=1
'loop:
'  for cnt1=1 to 8
'  pins=cnt2^$ff
 ' cnt2=cnt2*2
'pause 2000
'next
'  dirs=%00000000
'  pause 3000
'goto test
   
   
top:
dirs=%11100100      ' power off, led off, atn low, dtr low
'     76543210
pins=%00000000
waitring:
  pulsout led,300   ' brief flash on the status led
  nap 6             ' one second nap
  if ri=1 then waitring
   
' now the phone is ringing, time to answer call.
incoming:
  high pwr          ' turn on power to modem
  high led          ' turn on the status led
  pause 1000        ' time to initialize
  cnt1=0            ' counter to allow time to DCD
   
waitdcd:            ' wait up to 45 seconds for carrier
  cnt1=cnt1+1 max 300
  pause 99
  lep=cnt1&7/$7     ' blink LED, 0.1 sec every 0.8 seconds
  if cnt1=300 AND ri=1  then top    ' time-out, except holding ri low can extend
  if dcd=1 then waitdcd     ' wait until dcd goes low
   
' now carrier has been detected, reset BS2
carrier:
  if rxd=0 then carrier  ' wait for BREAK if present to clear
  high led          ' LED on
  low atn           ' get ready to reset the BS2 (OWL2c)
  pause 100         ' just in case
  high atn          ' reset the OWL2c, BS2
  low atn
  pause 2000        ' wait 2 seconds
'  input atn        ' now monitor for request from BS2 (not impemented here)
   
' now we enter the active loop, 
' monitoring DCD for loss of carrier
' ati as input from BS2, for hangup request from BS2
' and rxd for BREAK request from remote.
active0:
  cnt1=0                    ' watchdog counters     
  cnt2=0
  cnt3=0
active: ' loop time = 8 milliseconds
  cnt1=cnt1+1  'ati*ati     ' advances when ati is high
                            ' resets when ati is low
                            ' counts time ati stays high
                            ' resets at about 1.0 minutes
  ' if cnt1>7523 then reset ' too long no action
  lep=cnt1/64^txd           ' led, .5 ON .5 OFF XOR txd
  if dcd=1 then reset       ' no carrier
  ati0=ati^1                ' ati0 is high when ati is low
  cnt2=cnt2+ati0*ati0       ' advances when ati0 is high
                            ' resets when ati0 is low
                            ' counts time ati0 stays low
                            ' resets at about 3 seconds
rxd0=rxd^1                ' rxd low makes rxd0 high
  cnt3=cnt3+rxd0*rxd0       ' count time rxd0 is high
                            ' detects BREAK on line
  if cnt3>30 then carrier   ' if >0.6 sec then break
goto active
  
   
reset:
  if ri=0 then active0      ' stay active if ri stays low (test mode)
  low atn                   ' make atn a low output
  high dtr                  ' hang up and reset
for cnt2=1 to 20             ' flash status led 20 times
  pulsout led,5000
  pause 50
next
  pulsout atn,100           ' reset BS2 (OWL)
  goto top
      
   


<top> <index> <home> logo < mailto:tracy@emesys.com>