Class: XBee::BaseCommandModeInterface

Inherits:
RFModule
  • Object
show all
Defined in:
lib/legacy/command_mode.rb

Constant Summary collapse

VERSION =

Version of this class

"1.0"

Instance Attribute Summary

Attributes inherited from RFModule

#api_mode, #command_character, #command_mode_timeout, #firmware_rev, #guard_time, #hardware_rev, #node_discover_timeout, #node_identifier, #operation_mode, #serial_number, #transmission_mode, #xbee_serialport, #xbee_uart_config

Instance Method Summary collapse

Methods inherited from RFModule

#in_command_mode, #read_timeout

Methods included from XBee

#getresults, new

Constructor Details

#initialize(xbee_usbdev_str, baud, data_bits, stop_bits, parity) ⇒ BaseCommandModeInterface

xbee_usbdev_str is a path to the device used to communicate with the XBee. Typically it may look like: /dev/tty.usbserial-A80081sF if you’re using a USB to serial converter or a device such as www.sparkfun.com/commerce/product_info.php?products_id=8687



13
14
15
16
17
18
19
20
21
# File 'lib/legacy/command_mode.rb', line 13

def initialize( xbee_usbdev_str, baud, data_bits, stop_bits, parity )
  # open serial port device to XBee
  @xbee_serialport = SerialPort.new( xbee_usbdev_str, baud.to_i, data_bits.to_i, stop_bits.to_i, parity )
  @xbee_serialport.read_timeout = self.read_timeout(:short)
  @baudcodes = { 1200 => 0, 2400 => 1, 4800 => 2, 9600 => 3, 19200 => 4, 38400 => 5, 57600 => 6, 115200 => 7 }
  @paritycodes = { :None => 0, :Even => 1, :Odd => 2, :Mark => 3, :Space => 4 }
  @iotypes = { :Disabled => 0, :ADC => 2, :DI => 3, :DO_Low => 4, :DO_High => 5,
               :Associated_Indicator => 1, :RTS => 1, :CTS => 1, :RS485_Low => 6, :RS485_High => 7 }
end

Instance Method Details

#attentionObject

Puts the XBee into AT command mode and insures that we can bring it to attention.

The expected return value is "OK"


28
29
30
31
32
33
34
35
36
# File 'lib/legacy/command_mode.rb', line 28

def attention
  @xbee_serialport.write("+++")
  sleep 1
  getresponse   # flush up to +++ response if needed
  # if XBee is already in command mode, there will be no response, so make an explicit
  # AT call to insure an OK response
  @xbee_serialport.write("AT\r")
  getresponse().strip.chomp if getresponse()
end

#baudObject

retrieves the baud rate of the device. Generally, this will be the same as the

rate you're currently using to talk to the device unless you've changed the device's
baud rate and are still in the AT command mode and/or have not exited command mode explicitly for
the new baud rate to take effect.


289
290
291
292
293
# File 'lib/legacy/command_mode.rb', line 289

def baud
  @xbee_serialport.write("ATBD\r")
  baudcode = getresponse
  @baudcodes.key( baudcode.to_i )
end

#baud!(baud_rate) ⇒ Object

sets the given baud rate into the XBee device. The baud change will not take

effect until the AT command mode times out or the exit command mode command is given.
acceptable baud rates are: 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
end


301
302
303
304
# File 'lib/legacy/command_mode.rb', line 301

def baud!( baud_rate )
   @xbee_serialport.write("ATBD#{@baudcodes[baud_rate]}\r")
   getresponse
end

#channelObject

returns the channel number of the XBee device. this value, along with the PAN ID,

and MY address determines the addressability of the device and what it can listen to


191
192
193
194
195
196
197
198
199
# File 'lib/legacy/command_mode.rb', line 191

def channel
  # channel often takes more than 1000ms to return data
  tmp = @xbee_serialport.read_timeout
  @xbee_serialport.read_timeout = read_timeout(:long)
  @xbee_serialport.write("ATCH\r")
  response = getresponse
  @xbee_serialport.read_timeout = tmp
  response.strip.chomp if response
end

#channel!(new_channel) ⇒ Object

sets the channel number of the device. The valid channel numbers are those of the 802.15.4 standard.



204
205
206
207
208
209
210
211
212
# File 'lib/legacy/command_mode.rb', line 204

def channel!(new_channel)
  # channel takes more than 1000ms to return data
  tmp = @xbee_serialport.read_timeout
  @xbee_serialport.read_timeout = read_timeout(:long)
  @xbee_serialport.write("ATCH#{new_channel}\r")
  response = getresponse
  @xbee_serialport.read_timeout = tmp
  response.strip.chomp if response
end

#destination_highObject

returns the high portion of the XBee device’s current destination address



158
159
160
161
# File 'lib/legacy/command_mode.rb', line 158

def destination_high
  @xbee_serialport.write("ATDH\r")
  getresponse
end

#destination_high!(high_addr) ⇒ Object

sets the high portion of the XBee device’s current destination address



166
167
168
169
# File 'lib/legacy/command_mode.rb', line 166

def destination_high!(high_addr)
  @xbee_serialport.write("ATDH#{high_addr}\r")
  getresponse
end

#destination_lowObject

returns the low portion of the XBee device’s current destination address



142
143
144
145
# File 'lib/legacy/command_mode.rb', line 142

def destination_low
  @xbee_serialport.write("ATDL\r")
  getresponse
end

#destination_low!(low_addr) ⇒ Object

sets the low portion of the XBee device’s destination address



150
151
152
153
# File 'lib/legacy/command_mode.rb', line 150

def destination_low!(low_addr)
  @xbee_serialport.write("ATDL#{low_addr}\r")
  getresponse
end

#dio(port) ⇒ Object

reads an i/o port configuration on the XBee for analog to digital or digital input or output (GPIO)

this method returns an I/O type symbol of:

  :Disabled
  :ADC
  :DI
  :DO_Low
  :DO_High
  :Associated_Indicator
  :RTS
  :CTS
  :RS485_Low
  :RS485_High

Not all DIO ports are capable of every configuration listed above.  This method will properly translate
the XBee's response value to the symbol above when the same value has different meanings from port to port.

The port parameter may be any symbol :D0 through :D8 representing the 8 I/O ports on an XBee


359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/legacy/command_mode.rb', line 359

def dio( port )
  at = "AT#{port.to_s}\r"
  @xbee_serialport.write( at )
  response = getresponse.to_i

  if response == 1  # the value of 1 is overloaded based on port number
    case port
    when :D5
      return :Associated_Indicator
    when :D6
      return :RTS
    when :D7
      return :CTS
    end
  else
    @iotypes.key(response)
  end

end

#dio!(port, iotype) ⇒ Object

configures an i/o port on the XBee for analog to digital or digital input or output (GPIO)

port parameter valid values are the symbols :D0 through :D8

iotype parameter valid values are symbols:
  :Disabled
  :ADC
  :DI
  :DO_Low
  :DO_High
  :Associated_Indicator
  :RTS
  :CTS
  :RS485_Low
  :RS485_High

note: not all iotypes are compatible with every port type, see the XBee manual for exceptions and semantics

note: it is critical you have upgraded firmware in your XBee or DIO ports 0-4 cannot be read
      (ie: ATD0 will return ERROR - this is an XBee firmware bug that's fixed in revs later than 1083)

note: tested with rev 10CD, fails with rev 1083


404
405
406
407
408
# File 'lib/legacy/command_mode.rb', line 404

def dio!( port, iotype )
  at = "AT#{port.to_s}#{@iotypes[iotype]}\r"
  @xbee_serialport.write( at )
  getresponse
end

#dio_change_detectObject

reads the bitfield values for change detect monitoring. returns a bitmask indicating

which DIO lines, 0-7 are enabled or disabled for change detect monitoring


414
415
416
417
# File 'lib/legacy/command_mode.rb', line 414

def dio_change_detect
  @xbee_serialport.write("ATIC\r")
  getresponse
end

#dio_change_detect!(hexbitmap) ⇒ Object

sets the bitfield values for change detect monitoring. The hexbitmap parameter is a bitmap

which enables or disables the change detect monitoring for any of the DIO ports 0-7


423
424
425
426
# File 'lib/legacy/command_mode.rb', line 423

def dio_change_detect!( hexbitmap )
  @xbee_serialport.write("ATIC#{hexbitmask}\r")
  getresponse
end

#exit_command_modeObject

exits the AT command mode - all changed parameters will take effect such as baud rate changes

after the exit is complete.   exit_command_mode does not permanently save the parameter changes
when it exits AT command mode.  In order to permanently change parameters, use the save! method


525
526
527
# File 'lib/legacy/command_mode.rb', line 525

def exit_command_mode
  @xbee_serialport.write("ATCN\r")
end

#fw_revObject

Retrieve XBee firmware version



41
42
43
44
45
# File 'lib/legacy/command_mode.rb', line 41

def fw_rev
  @xbee_serialport.write("ATVR\r")
  response = getresponse
  response.strip.chomp if response
end

#getresponse(echo = false) ⇒ Object

returns results from the XBee

echo is disabled by default


540
541
542
# File 'lib/legacy/command_mode.rb', line 540

def getresponse( echo = false )
  getresults( @xbee_serialport, echo )
end

#hw_revObject

Retrieve XBee hardware version



50
51
52
53
54
# File 'lib/legacy/command_mode.rb', line 50

def hw_rev
  @xbee_serialport.write("ATHV\r")
  response = getresponse
  response.strip.chomp if response
end

#io_inputObject

Forces a sampling of all DIO pins configured for input via dio!

Returns a hash with the following key/value pairs:
:NUM => number of samples
:CM => channel mask
:DIO => dio data if DIO lines are enabled
:ADCn => adc sample data (one for each ADC channel enabled)


446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# File 'lib/legacy/command_mode.rb', line 446

def io_input

  tmp = @xbee_serialport.read_timeout
  @xbee_serialport.read_timeout = read_timeout(:long)

  @xbee_serialport.write("ATIS\r")
  response = getresponse
  linenum = 1
  adc_sample = 1
  samples = Hash.new

  if response.match("ERROR")
    samples[:ERROR] = "ERROR"
    return samples
  end

  # otherwise parse input data
  response.each_line do | line |
    case linenum
    when 1
      samples[:NUM] = line.to_i
    when 2
      samples[:CM] = line.strip.chomp if line
    when 3
      samples[:DIO] = line.strip.chomp if line
    else
      sample = line.strip.chomp if line
      if ( !sample.nil? && sample.size > 0 )
        samples["ADC#{adc_sample}".to_sym] = line.strip.chomp if line
        adc_sample += 1
      end
    end

    linenum += 1
  end

  @xbee_serialport.read_timeout = tmp
  samples
end

#io_output!(hexbitmap) ⇒ Object

Sets the digital output levels of any DIO lines which were configured for output using the dio! method.

The parameter, hexbitmap, is a hex value which represents the 8-bit bitmap of the i/o lines on the
XBee.


433
434
435
436
# File 'lib/legacy/command_mode.rb', line 433

def io_output!( hexbitmap )
  @xbee_serialport.write("ATIO#{hexbitmap}\r")
  getresponse
end

#my_src_addressObject

returns the source address of the XBee device - the MY address value



124
125
126
127
# File 'lib/legacy/command_mode.rb', line 124

def my_src_address
  @xbee_serialport.write("ATMY\r")
  getresponse.strip.chomp if getresponse
end

#my_src_address!(new_addr) ⇒ Object

sets the 16-bit source address of the XBee device. The parameter should be a 16-bit hex value.

The factory default is 0.  By setting the MY src address to 0xffff, 16-bit addressing is disabled
and the XBee will not listen for packets with 16-bit address fields


134
135
136
137
# File 'lib/legacy/command_mode.rb', line 134

def my_src_address!(new_addr)
  @xbee_serialport.write("ATMY#{new_addr}\r")
  getresponse
end

#neighborsObject

Neighbor node discovery. Returns an array of hashes each element of the array contains a hash

each hash contains keys:  :MY, :SH, :SL, :DB, :NI
representing addresses source address, Serial High, Serial Low, Received signal strength,
node identifier respectively.  Aan example of the results returned (hash as seen by pp):

  [{:NI=>" ", :MY=>"0", :SH=>"13A200", :SL=>"4008A642", :DB=>-24},
   {:NI=>" ", :MY=>"0", :SH=>"13A200", :SL=>"4008A697", :DB=>-33},
   {:NI=>" ", :MY=>"0", :SH=>"13A200", :SL=>"40085AD5", :DB=>-52}]

Signal strength (:DB) is reported in units of -dBM.


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/legacy/command_mode.rb', line 68

def neighbors
  # neighbors often takes more than 1000ms to return data
  tmp = @xbee_serialport.read_timeout
  @xbee_serialport.read_timeout = read_timeout(:long)
  @xbee_serialport.write("ATND\r")
  response = getresponse

  # parse nodes and stuff an array of hashes
  @neighbors = Array.new
  linetype = 0
  neighbor = 0

  if response.nil?
    return @neighbors   # return an empty array
  end

  response.each_line do | line |

    line.chomp!

    if line.size > 0
      case linetype
      when 0    # MY
          @neighbors[ neighbor ] = Hash.new
          @neighbors[ neighbor ].store( :MY, line )

      when 1    # SH
          @neighbors[ neighbor ].store( :SH, line )

      when 2    # SL
          @neighbors[ neighbor ].store( :SL, line )

      when 3    # DB
          @neighbors[ neighbor ].store( :DB, -(line.hex) )

      when 4    # NI
          @neighbors[ neighbor ].store( :NI, line )

          neighbor += 1
      end

      if linetype < 4
        linetype += 1
      else
        linetype = 0
      end
    end
  end

  @xbee_serialport.read_timeout = tmp
  @neighbors
end

#node_idObject

returns the node ID of the device. Node ID is typically a human-meaningful name

to give to the XBee device, much like a hostname.


218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/legacy/command_mode.rb', line 218

def node_id
  tmp = @xbee_serialport.read_timeout
  @xbee_serialport.read_timeout = read_timeout(:long)
  @xbee_serialport.write("ATNI\r")
  response = getresponse
  @xbee_serialport.read_timeout = tmp
  if ( response.nil? )
    return ""
  else
    response.strip.chomp 
  end
end

#node_id!(new_id) ⇒ Object

sets the node ID to a user-definable text string to make it easier to

identify the device with "human" names.  This node id is reported to
neighboring XBees so consider it "public".


236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/legacy/command_mode.rb', line 236

def node_id!(new_id)
  tmp = @xbee_serialport.read_timeout
  @xbee_serialport.read_timeout = read_timeout(:long)
  @xbee_serialport.write("ATNI#{new_id}\r")
  response = getresponse
  @xbee_serialport.read_timeout = tmp
  if ( response.nil? )
    return ""
  else
    response.strip.chomp
  end
end

#pan_idObject

returns the PAN ID of the device. PAN ID is one of the 3 main identifiers used to

communicate with the device from other XBees.  All XBees which are meant to communicate
must have the same PAN ID and channel number.  The 3rd identifier is the address of the
device itself represented by its serial number (High and Low) and/or it's 16-bit MY
source address.


255
256
257
258
# File 'lib/legacy/command_mode.rb', line 255

def pan_id
  @xbee_serialport.write("ATID\r")
  getresponse
end

#pan_id!(new_id) ⇒ Object

sets the PAN ID of the device. Modules must have the same PAN ID in order to communicate

with each other.  The PAN ID value can range from 0 - 0xffff.  The default from the factory
is set to 0x3332.


265
266
267
268
# File 'lib/legacy/command_mode.rb', line 265

def pan_id!(new_id)
  @xbee_serialport.write("ATID#{new_id}\r")
  getresponse
end

#parityObject

returns the parity of the device as represented by a symbol:

:None - for 8-bit none
:Even - for 8-bit even
:Odd  - for 8-bit odd
:Mark - for 8-bit mark
:Space - for 8-bit space


314
315
316
317
318
# File 'lib/legacy/command_mode.rb', line 314

def parity
  @xbee_serialport.write("ATNB\r")
  response = getresponse().strip.chomp if getresponse()
  @paritycodes.key( response.to_i )
end

#parity!(parity_type) ⇒ Object

sets the parity of the device to one represented by a symbol contained in the parity_type parameter

:None - for 8-bit none
:Even - for 8-bit even
:Odd  - for 8-bit odd
:Mark - for 8-bit mark
:Space - for 8-bit space


328
329
330
331
332
333
334
335
# File 'lib/legacy/command_mode.rb', line 328

def parity!( parity_type )
  # validate symbol before writing parity param
  if !@paritycodes.include?(parity_type)
    return false
  end
  @xbee_serialport.write("ATNB#{@paritycodes[parity_type]}\r")
  getresponse
end

#received_signal_strengthObject

returns the signal strength in dBm units of the last received packet. Expect a negative integer

or 0 to be returned.  If the XBee device has not received any neighboring packet data, the signal strength
value will be 0


275
276
277
278
279
280
281
# File 'lib/legacy/command_mode.rb', line 275

def received_signal_strength
  @xbee_serialport.write("ATDB\r")
  response = getresponse().strip.chomp if getresponse()
  # this response is an absolute hex value which is in -dBm
  # modify this so it returns actual - dBm value
  dbm = -(response.hex) if response
end

#reset!Object

resets the XBee module through software and simulates a power off/on. Any configuration

changes that have not been saved with the save! method will be lost during reset.


499
500
501
# File 'lib/legacy/command_mode.rb', line 499

def reset!
  @xbee_serialport.write("ATFR\r")
end

#restore!Object

Restores all the module parameters to factory defaults



506
507
508
# File 'lib/legacy/command_mode.rb', line 506

def restore!
  @xbee_serialport.write("ATRE\r")
end

#save!Object

writes the current XBee configuration to the XBee device’s flash. There

is no undo for this operation


490
491
492
493
# File 'lib/legacy/command_mode.rb', line 490

def save!
  @xbee_serialport.write("ATWR\r")
  getresponse
end

#send!(message) ⇒ Object

just a straight pass through of data to the XBee. This can be used to send

data when not in AT command mode, or if you want to control the XBee with raw
commands, you can send them this way.


515
516
517
# File 'lib/legacy/command_mode.rb', line 515

def send!(message)
  @xbee_serialport.write( message )
end

#serial_num_highObject

returns the high portion of the XBee devices serial number. this value is factory set.



182
183
184
185
# File 'lib/legacy/command_mode.rb', line 182

def serial_num_high
  @xbee_serialport.write("ATSH\r")
  getresponse
end

#serial_num_lowObject

returns the low portion of the XBee device’s serial number. this value is factory set.



174
175
176
177
# File 'lib/legacy/command_mode.rb', line 174

def serial_num_low
  @xbee_serialport.write("ATSL\r")
  getresponse
end

#versionObject

returns the version of this class



532
533
534
# File 'lib/legacy/command_mode.rb', line 532

def version
  VERSION
end