# nxt.sensor.mindsensors module -- Classes implementing Mindsensors sensors # Copyright (C) 2006,2007 Douglas P Lau # Copyright (C) 2009 Marcus Wanner, Paulo Vieira, rhn # Copyright (C) 2010 Marcus Wanner, MindSensors # # This program 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. # # This program 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. from .common import * from .digital import BaseDigitalSensor, SensorInfo from .analog import BaseAnalogSensor class SumoEyes(BaseAnalogSensor): """The class to control Mindsensors Sumo sensor. Warning: long range not working for my sensor. """ #range: 5-10cm class Reading: """Contains the reading of SumoEyes sensor. left and right can be True or False. If True, then there is something there, if False, then it's empty there. """ def __init__(self, raw_reading): self.raw = raw_reading val = raw_reading.normalized_ad_value # FIXME: make it rely on raw_ad_value right = 600 < val < 700 both = 700 <= val < 900 left = 300 < val < 400 self.left = left or both self.right = right or both def __str__(self): return '(left: ' + str(self.left) + ', right: ' + str(self.right) + ')' def __init__(self, brick, port, long_range=False): super(SumoEyes, self).__init__(brick, port) self.set_long_range(long_range) def set_long_range(self, val): """Sets if the sensor should operate in long range mode (12 inches) or the short range mode (6 in). val should be True or False. """ if val: type_ = Type.LIGHT_INACTIVE else: type_ = Type.LIGHT_ACTIVE self.set_input_mode(type_, Mode.RAW) def get_sample(self): """Returns the processed meaningful values of the sensor""" return self.Reading(self.get_input_values()) class Compassv2(BaseDigitalSensor): """Class for the now-discontinued CMPS-Nx sensor. Also works with v1.1 sensors. Note that when using a v1.x sensor, some of the commands are not supported! To determine your sensor's version, use get_sensor_info().version""" I2C_ADDRESS = BaseDigitalSensor.I2C_ADDRESS.copy() I2C_ADDRESS.update({'command': (0x41, '> 4 return str(gs3) + str(gs2) def get_minutes(self): gm = self.read_value('minutes')[0] gm2 = gm & 0xf gm3 = gm & 0x70 gm3 = gm3 >> 4 return str(gm3) + str(gm2) def get_hours(self): gh = self.read_value('hours')[0] gh2 = gh & 0xf gh3 = gh & 0x30 gh3 = gh3 >> 4 return str(gh3) + str(gh2) def get_day(self): gwd = self.read_value('day')[0] gwd = gwd & 0x07 return gwd def get_month(self): gmo = self.read_value('month')[0] gmo2 = gmo & 0xf gmo3 = gmo & 0x10 gmo3 = gmo3 >> 4 return str(gmo3) + str(gmo2) def get_year(self): """Last two digits (10 for 2010)""" gy = self.read_value('year')[0] gy2 = gy & 0xf gy3 = gy & 0xF0 gy3 = gy3 >> 4 return str(gy3) + str(gy2) def get_date(self): gd = self.read_value('date')[0] gd2 = gd & 0xf gd3 = gd & 0x60 gd3 = gd3 >> 4 return str(gd3) + str(gd2) def hour_mode(self, mode): """Writes mode bit and re-enters hours, which is required""" if mode == 12 or 24: hm = self.read_value('hours')[0] hm2 = hm & 0x40 hm2 = hm2 >> 6 if mode == 12 and hm2 == 0: #12_HOUR = 1 hm3 = hm + 64 self.write_value('hours', (hm3, )) elif mode == 24 and hm2 == 1: #24_HOUR = 0 hm3 = hm - 64 self.write_value('hours', (hm3, )) else: print 'That mode is already selected!' else: raise ValueError('Must be 12 or 24!') def get_mer(self): mer = self.read_value('hours')[0] mer2 = mer & 0x40 mer2 = mer2 >> 6 if mer2 == 1: mer3 = mer & 0x20 mer3 = mer3 >> 0x10 return mer3 else: print 'Cannot get mer! In 24-hour mode!' def get_sample(self): """Returns a struct_time() tuple which can be processed by the time module.""" import time return time.struct_time(( int(self.get_year())+2000, int(self.get_month()), int(self.get_date()), int(self.get_hours()), int(self.get_minutes()), int(self.get_seconds()), int(self.get_day()), 0, #Should be the Julian Day, but computing that is hard. 0 #No daylight savings time to worry about here. )) class ACCL(BaseDigitalSensor): """Class for Accelerometer sensor""" I2C_ADDRESS = BaseDigitalSensor.I2C_ADDRESS.copy() I2C_ADDRESS.update({'sensitivity': (0x19, 'B'), 'command': (0x41, 'B'), 'x_tilt': (0x42, 'b'), 'y_tilt': (0x43, 'b'), 'z_tilt': (0x44, 'b'), 'all_tilt': (0x42, '3b'), 'x_accel': (0x45, '> bit_num return value def get_tasks(self, motor_number): addressname = 'tasks_running_m' + str(motor_number) return self.read_value(addressname)[0] def set_pid(self, pid, target, value): addressname = str(pid) + '_' + str(target) self.write_value(addressname, (value, )) def set_pass_count(self, value): self.write_value('pass_count', (value, )) def set_tolerance(self, value): self.write_value('tolerance', (value, )) MMX.add_compatible_sensor(None, 'mndsnsrs', 'NxTMMX') #Tested with version 'V1.01' class HID(BaseDigitalSensor): """Class for Human Interface Device sensors. These are connected to a computer and look like a keyboard to it.""" I2C_ADDRESS = BaseDigitalSensor.I2C_ADDRESS.copy() I2C_ADDRESS.update({'command' : (0x41, '