All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rapplogic.xbee.api.zigbee.ZNetRxIoSampleResponse Maven / Gradle / Ivy

/**
 * Copyright (c) 2008 Andrew Rapp. All rights reserved.
 *  
 * This file is part of XBee-API.
 *  
 * XBee-API is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * XBee-API is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with XBee-API.  If not, see .
 */

package com.rapplogic.xbee.api.zigbee;

import java.io.IOException;

import org.apache.log4j.Logger;

import com.rapplogic.xbee.api.AtCommandResponse;
import com.rapplogic.xbee.api.IPacketParser;
import com.rapplogic.xbee.api.NoRequestResponse;
import com.rapplogic.xbee.api.XBeeParseException;
import com.rapplogic.xbee.util.ByteUtils;
import com.rapplogic.xbee.util.IIntInputStream;
import com.rapplogic.xbee.util.IntArrayInputStream;

/**
 * Series 2 XBee.  Represents an I/O Sample response sent from a remote radio.
 * Provides access to the XBee's 4 Analog (0-4), 11 Digital (0-7,10-12), and 1 Supply Voltage pins
 * 

* Note: Series 2 XBee does not support multiple samples (IT) per packet *

* @author andrew * */ public class ZNetRxIoSampleResponse extends ZNetRxBaseResponse implements NoRequestResponse { private final static Logger log = Logger.getLogger(ZNetRxIoSampleResponse.class); private int digitalChannelMaskMsb; private int digitalChannelMaskLsb; private int analogChannelMask; // all values that may not be in the packet use Integer to distinguish between null and non-null private Integer dioMsb; private Integer dioLsb; private final static int SUPPLY_VOLTAGE_INDEX = 4; private Integer[] analog = new Integer[5]; public ZNetRxIoSampleResponse() { } public static ZNetRxIoSampleResponse parseIsSample(AtCommandResponse response) throws IOException { if (!response.getCommand().equals("IS")) { throw new RuntimeException("This is only applicable to the \"IS\" AT command"); } IntArrayInputStream in = new IntArrayInputStream(response.getValue()); ZNetRxIoSampleResponse sample = new ZNetRxIoSampleResponse(); sample.parseIoSample(in); return sample; } public void parse(IPacketParser parser) throws IOException { this.parseAddress(parser); this.parseOption(parser); this.parseIoSample((IIntInputStream)parser); } /** * This method is a bit non standard since it needs to parse an IO sample * from either a RX response or a Remote AT/Local AT response (IS). * * @param ps * @throws IOException */ public void parseIoSample(IIntInputStream parser) throws IOException { // eat sample size.. always 1 int size = parser.read("ZNet RX IO Sample Size"); if (size != 1) { throw new XBeeParseException("Sample size is not supported if > 1 for ZNet I/O"); } this.setDigitalChannelMaskMsb(parser.read("ZNet RX IO Sample Digital Mask 1")); this.setDigitalChannelMaskLsb(parser.read("ZNet RX IO Sample Digital Mask 2")); this.setAnalogChannelMask(parser.read("ZNet RX IO Sample Analog Channel Mask")); // zero out n/a bits this.analogChannelMask = this.analogChannelMask & 0x8f; //10001111 // zero out all but bits 3-5 // TODO apparent bug: channel mask on ZigBee Pro firmware has DIO10/P0 as enabled even though it's set to 01 (RSSI). Digital value reports low. this.digitalChannelMaskMsb = this.digitalChannelMaskMsb & 0x1c; //11100 if (this.containsDigital()) { log.info("response contains digital data"); // next two bytes are digital this.setDioMsb(parser.read("ZNet RX IO DIO MSB")); this.setDioLsb(parser.read("ZNet RX IO DIO LSB")); } else { log.info("response does not contain digital data"); } // parse 10-bit analog values int enabledCount = 0; for (int i = 0; i < 4; i++) { if (this.isAnalogEnabled(i)) { log.info("response contains analog[" + i + "]"); analog[i] = ByteUtils.parse10BitAnalog(parser, enabledCount); enabledCount++; } } if (this.isSupplyVoltageEnabled()) { analog[SUPPLY_VOLTAGE_INDEX] = ByteUtils.parse10BitAnalog(parser, enabledCount); enabledCount++; } log.debug("There are " + analog + " analog inputs in this packet"); } public int getDigitalChannelMaskMsb() { return digitalChannelMaskMsb; } private void setDigitalChannelMaskMsb(int digitalChannelMask1) { this.digitalChannelMaskMsb = digitalChannelMask1; } public int getDigitalChannelMaskLsb() { return digitalChannelMaskLsb; } private void setDigitalChannelMaskLsb(int digitalChannelMask2) { this.digitalChannelMaskLsb = digitalChannelMask2; } public int getAnalogChannelMask() { return analogChannelMask; } private void setAnalogChannelMask(int analogChannelMask) { this.analogChannelMask = analogChannelMask; } /** * Consider using isDigitalEnabled(pin) instead * * @return */ public boolean isD0Enabled() { return this.isDigitalEnabled(0); } public boolean isD1Enabled() { return this.isDigitalEnabled(1); } public boolean isD2Enabled() { return this.isDigitalEnabled(2); } public boolean isD3Enabled() { return this.isDigitalEnabled(3); } public boolean isD4Enabled() { return this.isDigitalEnabled(4); } public boolean isD5Enabled() { return this.isDigitalEnabled(5); } public boolean isD6Enabled() { return this.isDigitalEnabled(6); } public boolean isD7Enabled() { return this.isDigitalEnabled(7); } public boolean isD10Enabled() { return this.isDigitalEnabled(10); } public boolean isD11Enabled() { return this.isDigitalEnabled(11); } public boolean isD12Enabled() { return this.isDigitalEnabled(12); } /** * Consider using isAnalogEnable(pin) instead * * @return */ public boolean isA0Enabled() { return this.isAnalogEnabled(0); } public boolean isA1Enabled() { return this.isAnalogEnabled(1); } public boolean isA2Enabled() { return this.isAnalogEnabled(2); } public boolean isA3Enabled() { return this.isAnalogEnabled(3); } public boolean isDigitalEnabled(int pin) { if (pin >=0 && pin <= 7) { return ByteUtils.getBit(this.digitalChannelMaskLsb, pin + 1); } else if (pin >=10 && pin <= 12) { return ByteUtils.getBit(this.digitalChannelMaskMsb, pin - 7); } else { throw new IllegalArgumentException("Unsupported pin: " + pin); } } public boolean isAnalogEnabled(int pin) { if (pin >=0 && pin <= 3) { return ByteUtils.getBit(this.analogChannelMask, pin + 1); } else { throw new IllegalArgumentException("Unsupported pin: " + pin); } } /** * (from the spec) The voltage supply threshold is set with the V+ command. If the measured supply voltage falls * below or equal to this threshold, the supply voltage will be included in the IO sample set. V+ is * set to 0 by default (do not include the supply voltage). * @return */ public boolean isSupplyVoltageEnabled() { return ByteUtils.getBit(this.analogChannelMask, 8); } /** * Consider using isDigitalOn(pin) * * @return */ public Boolean isD0On() { if (isDigitalEnabled(0)) { return isDigitalOn(0); } return null; } // consider using underscore for readability (isD1_On) public Boolean isD1On() { if (isDigitalEnabled(1)) { return isDigitalOn(1); } return null; } public Boolean isD2On() { if (isDigitalEnabled(2)) { return isDigitalOn(2); } return null; } public Boolean isD3On() { if (isDigitalEnabled(3)) { return isDigitalOn(3); } return null; } public Boolean isD4On() { if (isDigitalEnabled(4)) { return isDigitalOn(4); } return null; } public Boolean isD5On() { if (isDigitalEnabled(5)) { return isDigitalOn(5); } return null; } public Boolean isD6On() { if (isDigitalEnabled(6)) { return isDigitalOn(6); } return null; } public Boolean isD7On() { if (isDigitalEnabled(7)) { return isDigitalOn(7); } return null; } public Boolean isD10On() { if (isDigitalEnabled(10)) { return isDigitalOn(10); } return null; } public Boolean isD11On() { if (isDigitalEnabled(11)) { return isDigitalOn(11); } return null; } public Boolean isD12On() { if (isDigitalEnabled(12)) { return isDigitalOn(12); } return null; } /** * If digital I/O line (DIO0) is enabled: returns true if digital 0 is HIGH (ON); false if it is LOW (OFF). * If digital I/O line is not enabled this method returns null as it has no value. *

* Important: the pin number corresponds to the logical pin (e.g. D4), not the physical pin number. *

* Digital I/O pins seem to report high when open circuit (unconnected) * * @return */ public Boolean isDigitalOn(int pin) { if (this.isDigitalEnabled(pin)) { if (pin >=0 && pin <= 7) { return ByteUtils.getBit(dioLsb, pin + 1); } else if (pin >=10 && pin <= 12) { return ByteUtils.getBit(dioMsb, pin - 7); } } return null; } /** * Returns true if this sample contains data from digital inputs * * See manual page 68 for byte bit mapping * * @return */ public boolean containsDigital() { return this.getDigitalChannelMaskMsb() > 0 || this.getDigitalChannelMaskLsb() > 0; } /** * Returns true if this sample contains data from analog inputs or supply voltage * * How does supply voltage get enabled?? * * See manual page 68 for byte bit mapping * * @return */ public boolean containsAnalog() { return this.getAnalogChannelMask() > 0; } /** * Returns the DIO MSB, only if sample contains digital; null otherwise * * @return */ public Integer getDioMsb() { return dioMsb; } private void setDioMsb(Integer dioMsb) { this.dioMsb = dioMsb; } /** * Returns the DIO LSB, only if sample contains digital; null otherwise * * @return */ public Integer getDioLsb() { return dioLsb; } private void setDioLsb(Integer dioLsb) { this.dioLsb = dioLsb; } /** * Consider using getAnalog(pin) instead * * @return */ public Integer getAnalog0() { return analog[0]; } public void setAnalog0(Integer analog0) { analog[0] = analog0; } public Integer getAnalog1() { return analog[1]; } public void setAnalog1(Integer analog1) { analog[1] = analog1; } public Integer getAnalog2() { return analog[2]; } public void setAnalog2(Integer analog2) { analog[2] = analog2; } public Integer getAnalog3() { return analog[3]; } public void setAnalog3(Integer analog3) { analog[3] = analog3; } /** * Returns a 10 bit value of ADC line 0, if enabled. * Returns null if ADC line 0 is not enabled. *

* The range of Digi XBee series 2 ADC is 0 - 1.2V and although I couldn't find this in the spec * a few google searches seems to confirm. When I connected 3.3V to just one of the ADC pins, it * displayed its displeasure by reporting all ADC pins at 1023. *

* Analog pins seem to float around 512 when open circuit *

* The reason this returns null is to prevent bugs in the event that you thought you were reading the * actual value when the pin is not enabled. * * @return */ public Integer getAnalog(int pin) { if (this.isAnalogEnabled(pin)) { return analog[pin]; } return null; } // public Integer getAnalog(int pin) { // // analog starts 19 bytes after MSB length, if no dio enabled // int startIndex = 18; // // if (!isAnalogEnabled(pin)) { // // this pin is not turned on // return null; // } // // if (this.containsDigital()) { // // make room for digital i/o // startIndex+=2; // } // // // start depends on how many pins before this pin are enabled // for (int i = 0; i < pin; i++) { // if (isAnalogEnabled(i)) { // startIndex+=2; // } // } // // return (this.getProcessedPacketBytes()[startIndex] << 8) + this.getProcessedPacketBytes()[startIndex + 1]; // } public Integer getSupplyVoltage() { return analog[SUPPLY_VOLTAGE_INDEX]; } public void setSupplyVoltage(Integer supplyVoltage) { analog[SUPPLY_VOLTAGE_INDEX] = supplyVoltage; } public String toString() { StringBuilder builder = new StringBuilder(); builder.append(super.toString()); if (this.containsDigital()) { for (int i = 0; i <= 7; i++) { if (this.isDigitalEnabled(i)) { builder.append(",digital[" + i + "]=" + (this.isDigitalOn(i) ? "high" : "low")); } } for (int i = 10; i <= 12; i++) { if (this.isDigitalEnabled(i)) { builder.append(",digital[" + i + "]=" + (this.isDigitalOn(i) ? "high" : "low")); } } } if (this.containsAnalog()) { for (int i = 0; i <= 3; i++) { if (this.isAnalogEnabled(i)) { builder.append(",analog[" + i + "]=" + this.getAnalog(i)); } } if (this.isSupplyVoltageEnabled()) { builder.append(",supplyVoltage=" + this.getSupplyVoltage()); } } return builder.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy