Наработки за 5 лет

This commit is contained in:
Дмитрий Рамазанов 2019-08-27 14:47:10 +05:00
commit f5582d88c3
56 changed files with 11117 additions and 0 deletions

BIN
.csync_journal.db Normal file

Binary file not shown.

BIN
.csync_journal.db-shm Normal file

Binary file not shown.

0
.csync_journal.db-wal Normal file
View File

1650
.owncloudsync.log Normal file

File diff suppressed because it is too large Load Diff

366
HXbot/HX.py Executable file
View File

@ -0,0 +1,366 @@
# -*- coding: utf-8 -*-
########################################
# HXbot utility module #
# EoF 2016 EoF@itphx.ru #
########################################
# I2C bus
I2C_BUS_NUMBER = 2
EXT_COM = 0xAA
XOR_SEQ = 0xFF
# VAR
REFLEX_ADDRESS = 0x04
REFLEX_RESPONSE_DELAY = 0.1 # Delay to get response after send command, sec
REFLEX_ERROR_LIMIT = 5
REFLEX_MOVE_TIMEOUT = 60
# COMMANDS
# Util
COM_PING = 0x01
COM_GET_TEMP = 0x02
COM_GET_DISTANCE = 0x03
# Stop
STOP = 0x0F
# Move
MOVE_FLAG = 0x04
MOVE_FLOAT = 0x10
MOVE_FWD1 = 0x11
MOVE_FWD2 = 0x12
MOVE_FWD3 = 0x13
MOVE_FWD4 = 0x14
MOVE_FWD5 = 0x15
MOVE_FWD6 = 0x16
MOVE_FWD7 = 0x17
MOVE_BREAK = 0x18
MOVE_REV7 = 0x19
MOVE_REV6 = 0x1A
MOVE_REV5 = 0x1B
MOVE_REV4 = 0x1C
MOVE_REV3 = 0x1D
MOVE_REV2 = 0x1E
MOVE_REV1 = 0x1F
# Steering
STEER_FLAG = 0x05
STEER_CENTER = 0x20
STEER_LEFT1 = 0x21
STEER_LEFT2 = 0x22
STEER_LEFT3 = 0x23
STEER_LEFT4 = 0x24
STEER_LEFT5 = 0x25
STEER_LEFT6 = 0x26
STEER_LEFT7 = 0x27
STEER_FIX_CENTER = 0x28
STEER_RIGHT7 = 0x29
STEER_RIGHT6 = 0x2A
STEER_RIGHT5 = 0x2B
STEER_RIGHT4 = 0x2C
STEER_RIGHT3 = 0x2D
STEER_RIGHT2 = 0x2E
STEER_RIGHT1 = 0x2F
# Head
HEAD_H_FLAG = 0x30
HEAD_V_FLAG = 0x31
HEAD_H_R_RANGE = 83
HEAD_H_L_RANGE = 94
HEAD_V_UP_RANGE = 90
HEAD_V_DOWN_RANGE = 25
HEAD_H_CENTER = 83
HEAD_V_CENTER = 150
# CONTROL SOURCE
CONTROL_SRC_NONE = 0x00
CONTROL_SRC_JOYSTICK = 0x01
CONTROL_SRC_IRREMOTE = 0x02
CONTROL_SRC_SERVER = 0x03
CONTROL_SRC_DB = 0x04
CONTROL_SRC_SUB1 = 0x11
CONTROL_SRC_SUB2 = 0x12
CONTROL_SRC_SUB3 = 0x13
CONTROL_SRC_SUB4 = 0x14
CONTROL_SRC_SUB5 = 0x15
CONTROL_SRC_DEFAULT = CONTROL_SRC_JOYSTICK
# MOVE STATES
MOVE_STATE_STOP = 0x00
MOVE_STATE_MOVE = 0x01
# STATUS
STATUS_INIT = 0x00
STATUS_READY = 0x01
STATUS_RUNNING = 0x02
STATUS_STOP = 0x03
STATUS_EXIT = 0x04
# STATUS STATES
#STATUS_STATE_OK = 0x00
#STATUS_STATE_WARNING = 0x01
#STATUS_STATE_ERROR = 0x02
#STATUS_STATE_LOWBAT1 = 0x03
#STATUS_STATE_LOWBAT2 = 0x04
# JOYSTICK
JOYSTICK_PATH = '/dev/input/js0'
JOYSTICK_READY_TIMEOUT = 60
# These constants were borrowed from linux/input.h
JOYSTICK_AXIS_NAMES = {
0x00: 'x',
0x01: 'y',
0x02: 'z',
0x03: 'rx',
0x04: 'ry',
0x05: 'rz',
0x06: 'trottle',
0x07: 'rudder',
0x08: 'wheel',
0x09: 'gas',
0x0a: 'brake',
0x10: 'hat0x',
0x11: 'hat0y',
0x12: 'hat1x',
0x13: 'hat1y',
0x14: 'hat2x',
0x15: 'hat2y',
0x16: 'hat3x',
0x17: 'hat3y',
0x18: 'pressure',
0x19: 'distance',
0x1a: 'tilt_x',
0x1b: 'tilt_y',
0x1c: 'tool_width',
0x20: 'volume',
0x28: 'misc',
}
JOYSTICK_BUTTON_NAMES = {
0x120: 'trigger',
0x121: 'thumb',
0x122: 'thumb2',
0x123: 'top',
0x124: 'top2',
0x125: 'pinkie',
0x126: 'base',
0x127: 'base2',
0x128: 'base3',
0x129: 'base4',
0x12a: 'base5',
0x12b: 'base6',
0x12f: 'dead',
0x130: 'a',
0x131: 'b',
0x132: 'c',
0x133: 'x',
0x134: 'y',
0x135: 'z',
0x136: 'tl',
0x137: 'tr',
0x138: 'tl2',
0x139: 'tr2',
0x13a: 'select',
0x13b: 'start',
0x13c: 'mode',
0x13d: 'thumbl',
0x13e: 'thumbr',
0x220: 'dpad_up',
0x221: 'dpad_down',
0x222: 'dpad_left',
0x223: 'dpad_right',
# XBox 360 controller uses these codes.
0x2c0: 'dpad_left',
0x2c1: 'dpad_right',
0x2c2: 'dpad_up',
0x2c3: 'dpad_down',
}
# JOYSTICK BINDS
JOYSTICK_MOVE_AXIS = 'y'
JOYSTICK_STEER_AXIS = 'x'
JOYSTICK_HEAD_V_AXIS = 'rz'
JOYSTICK_HEAD_H_AXIS = 'z'
JOYSTICK_START_BTN_1 = 'tl2'
JOYSTICK_START_BTN_2 = 'tr2'
# HXpower
POWER_ADDRESS = 0x05
POWER_RESPONSE_DELAY = 0.05 # Delay to get response after send command, sec
POWER_DELAY = 0.3
POWER_ERROR_LIMIT = 3
POWER_MV_TIMEOUT = 60
# Commands
# VOLTMETERS
COM_GET_VIN = 0x01
COM_GET_VDC = 0x02
COM_GET_VBT = 0x03
COM_GET_VBA = 0x04
COM_GET_VPF = 0x05
COM_GET_VZU = 0x06
COM_GET_VCC = 0x07
# AMPERMETERS
COM_GET_ABT = 0x21
COM_GET_ABA = 0x22
COM_GET_AIN = 0x23
COM_GET_AHX = 0x24
# STATUS
COM_GET_STAT1 = 0x08
# 0x01 - vcc_ok
# 0x02 - vin_ok
# 0x04 - vdc_ok
# 0x08 - vbt_ok
# 0x10 - vba_ok
# 0x20 - bt_enabled
# 0x40 - ba_enabled
# 0x80 - in_plugged
COM_GET_STAT2 = 0x09
# 0x01 - bt_blocked
# 0x02 - ba_blocked
# 0x04 - bt_full
# 0x08 - ba_full
# 0x10 - vpf_ok
# 0x20 - vzu_ok
# 0x40 - mv_enabled
# 0x80 - us_enabled
COM_GET_STAT3 = 0x20
# 0x01 - abt_ok
# 0x02 - aba_ok
# 0x04 - ain_ok
# 0x08 - ahx_ok
# TEMP
COM_GET_POWER_TEMP = 0x10
VIN_MIN = 10.0
VIN_MAX = 14.0
VIN_LOW = 11.0
VIN_HIGH = 13.0
VDC_MIN = 5.0
VDC_MAX = 5.7
VDC_LOW = 5.1
VDC_HIGH = 5.5
VBT_MIN = 3.65
VBT_MAX = 4.25
VBT_LOW = 3.68
VBT_FULL = 4.1
VBA_MIN = 9.0
VBA_MAX = 12.8
VBA_LOW = 10.0
VBA_FULL = 12.4
VPF_MIN = 7.2
VPF_MAX = 10.0
VPF_LOW = 8.0
VPF_HIGH = 9.6
VZU_MIN = 5.0
VZU_MAX = 6.3
VZU_LOW = 5.2
VZU_HIGH = 6.2
VCC_MIN = 4.5
VCC_MAX = 5.3
VCC_LOW = 4.7
VCC_HIGH = 5.1
ABT_MIN = 0.3
ABT_MAX = 2.0
ABT_LOW = 0.4
ABT_HIGH = 1.2
ABA_MIN = 0.05
ABA_MAX = 2.0
ABA_LOW = 0.5
ABA_HIGH = 1.5
AIN_MIN = 0.05
AIN_MAX = 2.0
AIN_LOW = 0.1
AIN_HIGH = 1.5
AHX_MIN = 0.05
AHX_MAX = 3.0
AHX_LOW = 0.1
AHX_HIGH = 1.5
# RELAYS
COM_ENABLE_BA = 0x11 # 17
COM_ENABLE_MV = 0x12 # 18
COM_ENABLE_BT = 0x13 # 19
COM_ENABLE_US = 0x14 # 20
COM_DISABLE_BA = 0x15 # 21
COM_DISABLE_MV = 0x16 # 22
COM_DISABLE_BT = 0x17 # 23
COM_DISABLE_US = 0x18 # 24
COM_RUN = 0x1B # 27
COM_STOP = 0x1C # 28
COM_RESET_US = 0x1D # 29
# HXserver
SRV_PORT = 50306
SRV_HOST = ''
SRV_CMD_GET_ALL = 0x01
SRV_TIMEOUT = 1
SRV_MAX_ERR_COUNT = 3
# RETURN CODES
# Universal return codes
OK_RSP = 0x00
NO_RSP = 0xFF
ERR_RSP = 0x01
BLK_RSP = 0x02
CSE_RSP = 0x03
IOE_RSP = 0x04
TMO_RSP = 0x05
# HXbot modul flags
I2C_BUS_ERR = 0x0001
HXPOWER_ERR = 0x0002
REFLEX_ERR = 0x0004
SERVER_ERR = 0x0008
JOYSTICK_WRN = 0x0010
HXCAMERA_WRN = 0x0020
HXLCD_WRN = 0x0040
HXDB_WRN = 0x0080
HXLIGHT_WRN = 0x0100
HXSOUND_WRN = 0x0200
HXLOG_WRN = 0x0400
# HXlcd
LCD_ADDRESS = 0x06
LCD_ERROR_LIMIT = 5
LCD_DELAY = 1
LCD_RESPONSE_DELAY = 0.05
# HXcam
CAM_MAX_WRN_COUNT = 3
CAM_DELAY = 1.0
CAM_STATE_STP = 0
CAM_STATE_RUN = 1
CAM_STATE_WRN = 2
CAM_STATE_ERR = 3
# HXdb
DB_DELAY = 10.0
DB_HOST = 'localhost'
DB_NAME = 'hxdb'
DB_USER = 'hxdb'
DB_PASS = 'hxdbP@S$'

711
HXbot/HXbot.py Executable file
View File

@ -0,0 +1,711 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
########################################
# HXbot main program #
# EoF 2016 EoF@itphx.ru #
########################################
import HX
import REflex
import HXjoystick
import HXpower
import HXserver
import HXcam
import HXlcd
import HXdb
import time
import smbus
import sys
import threading
import RPi.GPIO as GPIO
# MAIN CLASS
class HXbotClass():
def __init__(self):
super(HXbotClass, self).__init__()
self.i2c_bus = None
self.hxpower = None
self.reflex = None
self.server = None
self.joystick = None
self.hxcam = None
self.hxlcd = None
self.hxdb = None
self.light = None
self.sound = None
self.log = None
self.status = HX.STATUS_INIT
self.hxpower_lock = threading.Lock()
self.reflex_lock = threading.Lock()
self.hxlcd_lock = threading.Lock()
self.hxdb_lock = threading.Lock()
def get_ready(self):
result = HX.OK_RSP
# Init I2C bus
try:
self.i2c_bus = smbus.SMBus(HX.I2C_BUS_NUMBER)
except IOError:
self.stop()
return result | HX.I2C_BUS_ERR
# Init hxpower
try:
self.hxpower = HXpower.HXpowerClass(self.i2c_bus, self.hxpower_lock)
except IOError:
self.stop()
return result | HX.HXPOWER_ERR
# Init reflex
try:
self.reflex = REflex.REflexClass(self)
except IOError:
self.stop()
return result | HX.REFLEX_ERR
# Init server
try:
self.server = HXserver.HXserverClass(self)
except OSError:
self.stop()
return result | HX.SERVER_ERR
# Init joystick
try:
self.joystick = HXjoystick.HXjoystickClass()
except OSError:
#self.joystick.stop()
#self.joystick = None
result |= HX.JOYSTICK_WRN
# Init hxcam
try:
self.hxcam = HXcam.HXcamClass()
except OSError:
self.hxcam.stop()
self.hxcam = None
result |= HX.HXCAMERA_WRN
# Init hxlcd
try:
self.hxlcd = HXlcd.HXlcdClass(self.i2c_bus, self.hxlcd_lock)
except OSError:
self.hxlcd.stop()
self.hxlcd = None
result |= HX.HXLCD_WRN
# Init hxdb
try:
self.hxdb = HXdb.HXdbClass(self)
except Exception:
#self.hxdb.stop()
self.hxdb = None
result |= HX.HXDB_WRN
# Init GPIO
GPIO.setmode(GPIO.BOARD)
#GPIO.setup(25, GPIO.OUT)
# Set status
self.status = True
return result
def start(self):
if self.status != HX.STATUS_READY:
return HX.BLK_RSP
# Start hxpower
self.hxpower.start()
# Start reflex
self.reflex.start()
# Start server
self.server.start()
# Start joystick
if self.joystick is not None:
self.joystick.start()
# Start camera
if self.hxcam is not None:
self.hxcam.start()
# Start lcd
if self.hxlcd is not None:
self.hxlcd.start()
# Start db
if self.hxdb is not None:
self.hxdb.start()
self.status = HX.STATUS_RUNNING
return HX.OK_RSP
def stop(self):
# Disable MV
self.hxpower.disable_mv()
# Disable camera
if self.hxcam:
# Stop process
if self.hxcam.is_running:
self.hxcam.stop()
# Clear property
self.hxcam = None
# Stop reflex
if self.reflex:
# Stop process
if self.reflex.is_running:
self.reflex.stop()
# Clear property
self.reflex = None
# Stop joystick
if self.joystick:
# Stop process
if self.joystick.is_running:
self.joystick.stop()
# Clear property
self.joystick = None
# Stop server
if self.server:
# Stop process
if self.server.is_running:
self.server.stop()
# Clear property
self.server = None
# Stop hxpower
if self.hxpower:
# Stop process
if self.hxpower.is_running:
self.hxpower.stop()
# Clear property
self.hxpower = None
# Stop hxlcd
if self.hxlcd:
# Stop process
if self.hxlcd.is_running:
self.hxlcd.stop()
# Clear property
self.hxlcd = None
# Stop hxdb
if self.hxdb:
# Stop process
if self.hxdb.is_running:
self.hxdb.stop()
# Clear property
self.hxdb = None
# Close I2C bus
if self.i2c_bus:
self.i2c_bus.close()
# Clear property
self.i2c_bus = None
# Set status
self.status = HX.STATUS_STOP
GPIO.cleanup()
return HX.OK_RSP
def get_temp(self):
try:
F = open("/sys/class/thermal/thermal_zone0/temp", "r")
T = float(F.read())
except IOError:
return -999
finally:
F.close()
return T / 1000
# MAIN PROGRAM
def main():
# INIT
print("Hi! I'am HXbot. Let's fun!'")
print("Type command or \"help\"")
# Create HXbot instance
hxbot = HXbotClass()
# Run
start(hxbot)
# MAIN LOOP
while True:
# Set command line view
if hxbot.status == HX.STATUS_INIT:
command_view = "INIT>"
elif hxbot.status == HX.STATUS_READY:
command_view = "READY>"
elif hxbot.status == HX.STATUS_RUNNING:
command_view = "RUNNING>"
elif hxbot.status == HX.STATUS_STOP:
command_view = "STOP>"
elif hxbot.status == HX.STATUS_EXIT:
command_view = "EXIT>"
command = input(command_view)
# COMMANDS
# Help
if command.lower() == "help":
print_help()
# Exit / Quit
elif command.lower() == "exit" or \
command.lower() == "quit":
stop(hxbot)
hxbot.status = HX.STATUS_EXIT
print("Exit...")
sys.exit()
# Status
elif command.lower() == "status":
print_status(hxbot)
# REflex control
elif command.lower() == "reflex":
reflex_control(hxbot)
# HXpower control
elif command.lower() == "hxpower":
hxpower_control(hxbot)
# HXcam control
elif command.lower() == "hxcam":
hxcam_control(hxbot)
# Get ready
elif command.lower() == "ready":
ready(hxbot)
# Start
elif command.lower() == "start":
start(hxbot)
# Stop
elif command.lower() == "stop":
stop(hxbot)
# Restart
elif command.lower() == "restart":
restart(hxbot)
# Test
elif command.lower() == "t":
t1 = time.clock()
print("t1:", t1)
time.sleep(5)
t2 = time.clock()
print("t2:", t2)
dt = t2 - t1
print("dt:", dt)
# WAT?
else:
print("WRONG COMMAND")
print("Try again or type \"help\"")
# EXIT
sys.exit()
# FUNCTIONS
def ready(hxbot):
if hxbot.status != HX.STATUS_READY:
print("Get ready...")
result = hxbot.get_ready()
print_result(result)
else:
print("HXbot already ready")
def start(hxbot):
if hxbot.status != HX.STATUS_RUNNING:
if hxbot.status != HX.STATUS_READY:
ready(hxbot)
print("Start...")
result = hxbot.start()
print_result(result)
else:
print("HXbot already running")
def stop(hxbot):
if hxbot.status != HX.STATUS_STOP:
print("Stop...")
result = hxbot.stop()
print_result(result)
else:
print("HXbot already stopped")
def restart(hxbot):
stop(hxbot)
ready(hxbot)
start(hxbot)
def print_help():
print("This is HXbot main program. You can type this commands:")
print("help - this help")
print("exit |")
print("quit - stop HXbot and exit")
print("status - get status")
print("start - start HXbot")
print("stop - stop HXbot")
print("restart - stop HXbot")
print("reflex - control REflex")
print("hxpower - control HXpower")
def hxpower_help():
print("This is HXpower control program. You can type this commands:")
print("help - this help")
print("exit - main menu")
print("bt - switch BT")
print("ba - switch BA")
print("mv - enable/disable moving")
print("us - enable/disable USB")
print("0-255 - send raw command")
def hxcam_help():
print("This is HXcam control program. You can type this commands:")
print("help - this help")
print("exit - main menu")
print("start - start HXcam")
print("stop - stop HXcam")
print("restart - restart HXcam")
def reflex_help():
print("This is REflex control program. You can type this commands:")
print("help - this help")
print("exit - main menu")
print("0-255 - send raw command")
def print_result(result):
# Universal return codes
if result == HX.OK_RSP:
print("OK")
elif result == HX.NO_RSP:
print("WARNING: No response")
elif result == HX.ERR_RSP:
print("ERROR")
elif result == HX.BLK_RSP:
print("ERROR: Blocked")
elif result == HX.CSE_RSP:
print("ERROR: Wrong control sum")
elif result == HX.BLK_RSP:
print("ERROR: ")
elif result == HX.IOE_RSP:
print("ERROR: Input/output error")
elif result == HX.TMO_RSP:
print("ERROR: Timeout")
# HXbot extended return codes
elif result == HX.I2C_BUS_ERR:
print("ERROR: I2C bus not ready")
elif result == HX.HXPOWER_ERR:
print("ERROR: HXpower not ready")
elif result == HX.JOYSTICK_WRN:
print("WARNING: Joystick not found")
elif result == HX.REFLEX_ERR:
print("ERROR: REflex not ready")
elif result == HX.SERVER_ERR:
print("ERROR: Server not ready")
elif result == HX.HXCAMERA_WRN:
print("WARNING: Camera not ready")
elif result == HX.HXLCD_WRN:
print("WARNING: LCD module not ready")
elif result == HX.HXDB_WRN:
print("WARNING: DB module not ready")
# Unknown return code
else:
print("WARNING: Unknown return code received")
def print_status(hxbot):
if (hxbot.status != HX.STATUS_READY and
hxbot.status != HX.STATUS_RUNNING):
print("HXbot is not in ready or running state!")
return
# Print voltages
print("Vcc =", hxbot.hxpower.vcc)
print("Vin =", hxbot.hxpower.vin)
print("Vdc =", hxbot.hxpower.vdc)
print("Vbt =", hxbot.hxpower.vbt)
print("Vba =", hxbot.hxpower.vba)
print("Vpf =", hxbot.hxpower.vpf)
print("Vzu =", hxbot.hxpower.vzu)
# Print currents
print("Abt =", hxbot.hxpower.abt)
print("Aba =", hxbot.hxpower.aba)
print("Ain =", hxbot.hxpower.ain)
print("Ahx =", hxbot.hxpower.ahx)
# Print temperature
print("CPU Temp:", hxbot.get_temp())
print("REflex Temp:", hxbot.reflex.get_temp())
#print("HXPower Temp:", )
# Print status
if hxbot.hxpower.vcc_ok:
print("Vcc - OK")
else:
print("Vcc - FAIL")
if hxbot.hxpower.vin_ok:
print("Vin - OK")
else:
print("Vin - FAIL")
if hxbot.hxpower.vdc_ok:
print("Vdc - OK")
else:
print("Vdc - FAIL")
if hxbot.hxpower.vbt_ok:
print("Vbt - OK")
else:
print("Vbt - FAIL")
if hxbot.hxpower.vba_ok:
print("Vba - OK")
else:
print("Vba - FAIL")
if hxbot.hxpower.vpf_ok:
print("Vpf - OK")
else:
print("Vpf - FAIL")
if hxbot.hxpower.vzu_ok:
print("Vzu - OK")
else:
print("Vzu - FAIL")
if hxbot.hxpower.abt_ok:
print("Abt - OK")
else:
print("Abt - FAIL")
if hxbot.hxpower.aba_ok:
print("Aba - OK")
else:
print("Aba - FAIL")
if hxbot.hxpower.ain_ok:
print("Ain - OK")
else:
print("Ain - FAIL")
if hxbot.hxpower.ahx_ok:
print("Ahx - OK")
else:
print("Ahx - FAIL")
if hxbot.hxpower.bt_enabled:
print("BT enabled")
else:
print("BT disabled")
if hxbot.hxpower.ba_enabled:
print("BA enabled")
else:
print("BA disabled")
if hxbot.hxpower.mv_enabled:
print("mv enabled")
else:
print("PF disabled")
if hxbot.hxpower.us_enabled:
print("USB power enabled")
else:
print("USB power disabled")
if hxbot.hxpower.bt_blocked:
print("BT blocked")
else:
print("BT unblocked")
if hxbot.hxpower.ba_blocked:
print("BA blocked")
else:
print("BA unblocked")
if hxbot.hxpower.in_plugged:
print("IN plugged")
else:
print("IN unplugged")
if hxbot.hxpower.bt_full:
print("BT charge complete")
if hxbot.hxpower.ba_full:
print("BA charge complete")
print()
def reflex_control(hxbot):
if (hxbot.status != HX.STATUS_READY and
hxbot.status != HX.STATUS_RUNNING):
print("HXbot is not in ready or running state!")
return
rawCommand = 0x00
rawResponse = 0x00
print("Reflex control program. Type command or \"help\"")
print("Type \"exit\" to previous menu")
command_view = "REflex control>"
while True:
command = input(command_view)
if command.lower() == "exit":
break
elif command.lower() == "help":
reflex_help()
else:
# Try to send RAW command to REflex
try:
rawCommand = int(command)
except:
rawCommand = 0x00
if not rawCommand:
continue
with hxbot.reflex_lock:
hxbot.i2c_bus.write_byte(HX.REFLEX_ADDRESS, rawCommand)
print("Sent: ", rawCommand)
time.sleep(HX.REFLEX_RESPONSE_DELAY)
rawResponse = hxbot.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
print("Received: ", rawResponse)
def hxpower_control(hxbot):
if (hxbot.status != HX.STATUS_READY and
hxbot.status != HX.STATUS_RUNNING):
print("HXbot is not in ready or running state!")
return
rawCommand = 0x00
rawResponse = 0x00
print("HXpower control program. Type command or \"help\"")
print("Type \"exit\" to previous menu")
command_view = "HXpower control>"
while True:
command = input(command_view)
if command.lower() == "exit":
break
elif command.lower() == "help":
hxpower_help()
elif command.lower() == "bt":
if hxbot.hxpower.bt_enabled:
print("Disable BT...")
result = hxbot.hxpower.disable_bt()
else:
print("Enable BT...")
result = hxbot.hxpower.enable_bt()
print_result(result)
elif command.lower() == "ba":
if hxbot.hxpower.ba_enabled:
print("Disable BA...")
result = hxbot.hxpower.disable_ba()
else:
print("Enable BA...")
result = hxbot.hxpower.enable_ba()
print_result(result)
elif command.lower() == "mv":
if hxbot.hxpower.mv_enabled:
print("Disable MV...")
result = hxbot.hxpower.disable_mv()
else:
print("Enable MV...")
result = hxbot.hxpower.enable_mv()
print_result(result)
elif command.lower() == "us":
if hxbot.hxpower.us_enabled:
print("Disable USB power...")
result = hxbot.hxpower.disable_us()
else:
print("Enable USB power...")
result = hxbot.hxpower.enable_us()
print_result(result)
elif command.lower() == "reset":
GPIO.output(25, 0)
time.sleep(5)
GPIO.output(25, 1)
else:
# Try to send RAW command to HXpower
try:
rawCommand = int(command)
except:
rawCommand = 0x00
print("Wrong command!")
if not rawCommand:
continue
rawCommand = (rawCommand << 8) | (rawCommand ^ HX.XOR_SEQ)
try:
with hxbot.hxpower_lock:
hxbot.i2c_bus.write_word_data(HX.POWER_ADDRESS,
HX.EXT_COM, rawCommand)
print("Sent:", rawCommand, "(", rawCommand, ")")
time.sleep(HX.POWER_RESPONSE_DELAY)
rawResponse = hxbot.i2c_bus.read_byte(HX.POWER_ADDRESS)
print("Received:", rawResponse)
except IOError as E:
print(E)
def hxcam_control(hxbot):
if (hxbot.status != HX.STATUS_READY and
hxbot.status != HX.STATUS_RUNNING):
print("HXbot is not in ready or running state!")
return
print("HXcam control program. Type command or \"help\"")
print("Type \"exit\" to previous menu")
command_view = "HXcam control>"
while True:
command = input(command_view)
if command.lower() == "exit":
break
elif command.lower() == "help":
hxcam_help()
elif command.lower() == "start":
print("Start HXcam")
if hxbot.hxcam.is_running:
print("Allready running")
else:
hxbot.hxcam.start()
elif command.lower() == "stop":
print("Stop HXcam")
if not hxbot.hxcam.is_running:
print("Not running")
else:
hxbot.hxcam.stop()
elif command.lower() == "restart":
print("Restart HXcam")
if hxbot.hxcam.is_running:
print("Stop...")
hxbot.hxcam.stop()
if not hxbot.hxcam.is_running:
print("Start...")
hxbot.hxcam.start()
# MAIN PROGRAM
if __name__ == "__main__":
main()

257
HXbot/HXcam.py Executable file
View File

@ -0,0 +1,257 @@
# -*- coding: utf-8 -*-
########################################
# HXbot camera control module #
# EoF 2016 EoF@itphx.ru #
########################################
import subprocess
import threading
#import select
import time
import sys
import os.path as path
import HX
class HXcamClass():
def __init__(self):
super(HXcamClass, self).__init__()
self.__e = None
self.__t = None
self.mcam = None
self.rcam = None
self.mmic = None
self.rvid = None
self.is_running = False
# Subprocess states
# 0 - Not running
# 1 - Running
# 2 - Error
# 3 - Device not found
self.mcam_state = HX.CAM_STATE_STP
self.rvid_state = HX.CAM_STATE_STP
self.rcam_state = HX.CAM_STATE_STP
self.mmic_state = HX.CAM_STATE_STP
self.mcam_wrn_count = 0
self.rcam_wrn_count = 0
self.mmic_wrn_count = 0
def start(self):
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.mcam_start()
#self.rcam_start()
self.mmic_start()
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.__e = None
self.__t = None
self.mcam_stop()
#self.rcam_stop()
self.mmic_stop()
self.is_running = False
def restart(self):
if self.is_running:
self.__stop()
self.__start()
def test(self):
#import time
#import sys
#import shlex
#string = ""
#args = shlex.split(string)
#print(args)
#sys.exit()
pass
def mcam_start(self):
# cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15'
# --sout '#rtp{sdp=rtsp://:8554/video}' -v --live-caching 50
if path.exists('/dev/video0'):
arg = 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15'
elif path.exists('/dev/video1'):
arg = 'v4l2:///dev/video1:chroma=H264:width=1280:height=720:fps=15'
else:
self.mcam_state = HX.CAM_STATE_ERR
return
self.mcam = subprocess.Popen(
args=['/usr/bin/cvlc',
arg,
'--sout', '#rtp{sdp=rtsp://:8554/video}',
'--live-caching', '50', 'vlc://quit'],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
self.mcam_state = HX.CAM_STATE_RUN
def mcam_stop(self):
if self.mcam_state != HX.CAM_STATE_ERR:
self.mcam.terminate()
self.mcam_state = HX.CAM_STATE_STP
def rcam_start(self):
# raspivid -t 0 -n -w 1280 -h 720 -fps 15 -o - |
# cvlc -v stream:///dev/stdin
# --sout '#rtp{sdp=rtsp://:8555/video}' :demux=h264
self.rvid = subprocess.Popen(
args=['raspivid', '-t', '0', '-n', '-w', '1280', '-h', '720',
'-fps', '15', '-o', '-'],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL)
self.rcam = subprocess.Popen(
args=['cvlc', 'stream:///dev/stdin', '--sout',
'#rtp{sdp=rtsp://:8555/video}', ':demux=h264',
'--live-caching', '50', 'vlc://quit'],
stdin=self.rvid.stdout,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
self.rcam_state = HX.CAM_STATE_RUN
def rcam_stop(self):
if self.rcam_state != HX.CAM_STATE_ERR:
self.rvid.terminate()
self.rcam.terminate()
self.rcam_state = HX.CAM_STATE_STP
def mmic_start(self):
# cvlc -v 'alsa://hw:1,0'
# --sout '#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100}
# :rtp{sdp=rtsp://:8556/audio}'
self.mmic = subprocess.Popen(
args=['cvlc', 'alsa://hw:0,0', '--sout',
'#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100}' +
':rtp{sdp=rtsp://:8556/audio}',
'--live-caching', '500', 'vlc://quit'],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
self.mmic_state = HX.CAM_STATE_RUN
def mmic_stop(self):
if self.mmic_state != HX.CAM_STATE_ERR:
self.mmic.terminate()
self.mmic_state = HX.CAM_STATE_STP
def __process(self, stopRequest):
# Process loop
while not stopRequest.is_set():
# Main Camera
if self.mcam_state != HX.CAM_STATE_ERR:
if self.mcam.poll() is not None:
self.mcam_start()
if self.mcam_state != HX.CAM_STATE_WRN:
self.mcam_wrn_count += 1
if self.mcam_wrn_count >= HX.CAM_MAX_WRN_COUNT:
self.mcam_state = HX.CAM_STATE_WRN
# Rear Camera
#if self.rcam_state != HX.CAM_STATE_ERR:
#if self.rcam.poll() is not None:
#self.rcam_start()
#if self.rcam_state != HX.CAM_STATE_WRN:
#self.rcam_wrn_count += 1
#if self.rcam_wrn_count >= HX.CAM_MAX_WRN_COUNT:
#self.rcam_state = HX.CAM_STATE_WRN
# Main Microphone
if self.mmic_state != HX.CAM_STATE_ERR:
if self.mmic.poll() is not None:
self.mmic_start()
if self.mmic_state != HX.CAM_STATE_WRN:
self.mmic_wrn_count += 1
if self.mmic_wrn_count >= HX.CAM_MAX_WRN_COUNT:
self.mmic_state = HX.CAM_STATE_WRN
time.sleep(HX.CAM_DELAY)
#if self.mcam_state == 1:
## VLC-1
#r, w, e = select.select([self.mcam.stderr], [], [], 0.5)
#if self.mcam.stderr in r:
#print("VLC-1 ERROR:")
#print(self.mcam.stderr.readline())
#r, w, e = select.select([self.mcam.stdout], [], [], 0.5)
#if self.mcam.stdout in r:
#print("VLC-1 OUT:")
#print(self.mcam.stdout.readline())
#if self.rvid_state == 1:
## VLC-2
#r, w, e = select.select([self.rvid.stderr], [], [], 0.5)
#if self.rvid.stderr in r:
#print("RVID ERROR:")
#print(self.rvid.stderr.readline())
#r, w, e = select.select([self.rcam.stderr], [], [], 0.5)
#if self.rcam.stderr in r:
#print("VLC-2 ERROR:")
#print(self.rcam.stderr.readline())
#r, w, e = select.select([self.rcam.stdout], [], [], 0.5)
#if self.rcam.stdout in r:
#print("VLC-2 OUT:")
#print(self.rcam.stdout.readline())
#if self.mmic_state == 1:
## VLC-3
#r, w, e = select.select([self.mmic.stderr], [], [], 0)
#if self.mmic.stderr in r:
#print("MMIC ERROR:")
#print(self.mmic.stderr.readline())
#r, w, e = select.select([self.mmic.stdout], [], [], 0.5)
#if self.mmic.stdout in r:
#print("MMIC OUT:")
#print(self.mmic.stdout.readline())
def main():
HXcam = HXcamClass()
HXcam.start()
print("Execution started")
command_view = '"Return" or CTRL+C to exit>'
try:
while True:
command = input(command_view)
if command == "":
HXcam.stop()
sys.exit()
except KeyboardInterrupt:
print("Terminate...")
HXcam.stop()
if __name__ == '__main__':
main()

132
HXbot/HXdb.py Executable file
View File

@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
########################################
# HXbot database module #
# EoF 2016 EoF@itphx.ru #
########################################
import HX
import threading
import time
import mysql.connector
from mysql.connector import errorcode
class HXdbClass():
def __init__(self, hxbot):
super(HXdbClass, self).__init__()
self.hxbot = hxbot
self.hxpower = None
self.reflex = None
self.joystick = None
self.hxlcd = None
self.hxcam = None
self.__e = None
self.__t = None
self.is_running = False
try:
self.cnx = mysql.connector.connect(user=HX.DB_USER,
password=HX.DB_PASS,
host=HX.DB_HOST,
database=HX.DB_NAME)
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something is wrong with your user name or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("Database does not exist")
else:
print(err)
self.cnx = None
raise
def start(self):
self.hxpower = self.hxbot.hxpower
self.reflex = self.hxbot.reflex
self.joystick = self.hxbot.joystick
self.hxlcd = self.hxbot.hxlcd
self.hxcam = self.hxbot.hxcam
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.is_running = False
if self.cnx is not None:
self.cnx.close()
self.hxpower = None
self.reflex = None
self.joystick = None
self.hxlcd = None
self.hxcam = None
self.__e = None
self.__t = None
def __process(self, stopRequest):
cursor = self.cnx.cursor()
pw = self.hxpower
insert_state = ("INSERT INTO states "
"(vcc, vin, vdc, vbt, vba, vis, vzu, "
"ahx, aba, ain, adc, "
"vcc_ok, vin_ok, vdc_ok, vbt_ok, vba_ok, "
"vis_ok, vzu_ok, "
"ahx_ok, aba_ok, ain_ok, adc_ok, "
"lr_enabled, ba_enabled, ba_blocked, "
"vcc_low, vcc_high, vin_low, vin_high, "
"vdc_low, vdc_high, vbt_low, vbt_full, "
"vba_low, vba_full, vis_low, vis_high, "
"vzu_low, vzu_high, "
"ahx_low, ahx_high, aba_low, aba_high, "
"ain_low, ain_high, adc_low, adc_high, "
"pf_enabled, bl_enabled, bl_powered, "
"bl_error, ba_full, ba_charge) "
"VALUES ("
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
"%s, %s, %s)")
while not stopRequest.is_set():
# Get Data
state = (pw.vcc, pw.vin, pw.vdc, pw.vbt, pw.vba, pw.vis,
pw.vzu, pw.ahx, pw.aba, pw.ain, pw.adc, pw.vcc_ok,
pw.vin_ok, pw.vdc_ok, pw.vbt_ok, pw.vba_ok,
pw.vis_ok, pw.vzu_ok,
pw.ahx_ok, pw.aba_ok, pw.ain_ok, pw.adc_ok,
pw.lr_enabled, pw.ba_enabled, pw.ba_blocked,
pw.vcc_low, pw.vcc_high, pw.vin_low, pw.vin_high,
pw.vdc_low, pw.vdc_high, pw.vbt_low, pw.vbt_full,
pw.vba_low, pw.vba_full, pw.vis_low, pw.vis_high,
pw.vzu_low, pw.vzu_high, pw.ahx_low, pw.ahx_high,
pw.aba_low, pw.aba_high, pw.ain_low, pw.ain_high,
pw.adc_low, pw.adc_high,
pw.pf_enabled, pw.bl_enabled,
pw.bl_powered, pw.bl_error,
pw.ba_full, pw.ba_charge)
# Insert Data
if pw.online:
cursor.execute(insert_state, state)
self.cnx.commit()
# Delay
time.sleep(HX.DB_DELAY)
cursor.close()

234
HXbot/HXjoystick.py Executable file
View File

@ -0,0 +1,234 @@
# -*- coding: utf-8 -*-
########################################
# HXbot controller module #
# EoF 2016 EoF@itphx.ru #
########################################
import HX
import threading
import array
import struct
import select
import time
from fcntl import ioctl
class HXjoystickClass():
def __init__(self):
super(HXjoystickClass, self).__init__()
self.__e = None
self.__t = None
self.ready = False
self.device = open(HX.JOYSTICK_PATH, 'rb')
self.name = ""
self.axis_states = {}
self.button_states = {}
self.axis_map = []
self.button_map = []
self.axis_names = HX.JOYSTICK_AXIS_NAMES
self.button_names = HX.JOYSTICK_BUTTON_NAMES
self.online = False
self.is_running = False
self.last_command_time = 0.0
# Get the device name.
buf = array.array('B', [0] * 64)
# JSIOCGNAME(len)
ioctl(self.device, 0x80006a13 + (0x10000 * len(buf)), buf)
self.name = buf.tostring()
#print('Device name: %s' % js_name)
# Get number of axes and buttons.
buf = array.array('B', [0])
ioctl(self.device, 0x80016a11, buf) # JSIOCGAXES
num_axes = buf[0]
buf = array.array('B', [0])
ioctl(self.device, 0x80016a12, buf) # JSIOCGBUTTONS
num_buttons = buf[0]
# Get the axis map.
buf = array.array('B', [0] * 0x40)
ioctl(self.device, 0x80406a32, buf) # JSIOCGAXMAP
for axis in buf[:num_axes]:
axis_name = self.axis_names.get(axis, 'unknown(0x%02x)' % axis)
self.axis_map.append(axis_name)
self.axis_states[axis_name] = 0.0
# Get the button map.
buf = array.array('H', [0] * 200)
ioctl(self.device, 0x80406a34, buf) # JSIOCGBTNMAP
for btn in buf[:num_buttons]:
btn_name = self.button_names.get(btn, 'unknown(0x%03x)' % btn)
self.button_map.append(btn_name)
self.button_states[btn_name] = 0
#print('%d axes found: %s' % (num_axes, ', '.join(self.axis_map)))
#print('%d btns found: %s' % (num_buttons, ', '.join(self.button_map)))
def start(self):
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.is_running = False
self.__e = None
self.__t = None
def __process(self, stopRequest):
while not stopRequest.is_set():
r, w, e = select.select([self.device], [], [], 0.8)
if self.device in r:
try:
evbuf = self.device.read(8)
self.online = True
except OSError:
self.online = False
self.ready = False
continue
if evbuf:
time_, value, type, number = struct.unpack('IhBB', evbuf)
# Save last command time
self.last_command_time = time.clock()
#if type & 0x80:
#print("(initial)")
if type & 0x01:
button = self.button_map[number]
if button:
self.button_states[button] = value
#if value:
#print("%s pressed" % (button))
#else:
#print("%s released" % (button))
if type & 0x02:
axis = self.axis_map[number]
if axis:
fvalue = value / 32767.0
self.axis_states[axis] = fvalue
#print("%s: %.3f" % (axis, fvalue))
# Switch ready property
if (self.button_states[HX.JOYSTICK_START_BTN_1] and
self.button_states[HX.JOYSTICK_START_BTN_2]):
if self.ready:
self.ready = False
else:
self.ready = True
# Timeout? Relax...
elif time.clock() - self.last_command_time >= \
HX.JOYSTICK_READY_TIMEOUT / 100:
self.ready = False
def get_m(self):
axis_move = self.axis_states[HX.JOYSTICK_MOVE_AXIS]
axis_steer = self.axis_states[HX.JOYSTICK_STEER_AXIS]
axis_head_v = self.axis_states[HX.JOYSTICK_HEAD_V_AXIS]
axis_head_h = self.axis_states[HX.JOYSTICK_HEAD_H_AXIS]
# STOP (FLOAT)
if (axis_move >= -1 / 8) and (axis_move <= 1 / 8):
move = HX.MOVE_FLOAT
# MOVE FORWARD
elif (axis_move >= -2 / 8) and (axis_move < -1 / 8):
move = HX.MOVE_FWD1
elif (axis_move >= -3 / 8) and (axis_move < -2 / 8):
move = HX.MOVE_FWD2
elif (axis_move >= -4 / 8) and (axis_move < -3 / 8):
move = HX.MOVE_FWD3
elif (axis_move >= -5 / 8) and (axis_move < -4 / 8):
move = HX.MOVE_FWD4
elif (axis_move >= -6 / 8) and (axis_move < -5 / 8):
move = HX.MOVE_FWD5
elif (axis_move >= -7 / 8) and (axis_move < -6 / 8):
move = HX.MOVE_FWD6
elif (axis_move >= -1) and (axis_move < -7 / 8):
move = HX.MOVE_FWD7
# MOVE BACKWARD
elif (axis_move > 1 / 8) and (axis_move <= 2 / 8):
move = HX.MOVE_REV1
elif (axis_move > 2 / 8) and (axis_move <= 3 / 8):
move = HX.MOVE_REV2
elif (axis_move > 3 / 8) and (axis_move <= 4 / 8):
move = HX.MOVE_REV3
elif (axis_move > 4 / 8) and (axis_move <= 5 / 8):
move = HX.MOVE_REV4
elif (axis_move > 5 / 8) and (axis_move <= 6 / 8):
move = HX.MOVE_REV5
elif (axis_move > 6 / 8) and (axis_move <= 7 / 8):
move = HX.MOVE_REV6
elif (axis_move > 7 / 8) and (axis_move <= 1):
move = HX.MOVE_REV7
# CENTER (FLOAT)
if (axis_steer >= -1 / 8) and (axis_steer <= 1 / 8):
steer = HX.STEER_CENTER
# STEER LEFT
elif (axis_steer >= -2 / 8) and (axis_steer < -1 / 8):
steer = HX.STEER_LEFT1
elif (axis_steer >= -3 / 8) and (axis_steer < -2 / 8):
steer = HX.STEER_LEFT2
elif (axis_steer >= -4 / 8) and (axis_steer < -3 / 8):
steer = HX.STEER_LEFT3
elif (axis_steer >= -5 / 8) and (axis_steer < -4 / 8):
steer = HX.STEER_LEFT4
elif (axis_steer >= -6 / 8) and (axis_steer < -5 / 8):
steer = HX.STEER_LEFT5
elif (axis_steer >= -7 / 8) and (axis_steer < -6 / 8):
steer = HX.STEER_LEFT6
elif (axis_steer >= -1) and (axis_steer < -7 / 8):
steer = HX.STEER_LEFT7
# STEER RIGHT
elif (axis_steer > 1 / 8) and (axis_steer <= 2 / 8):
steer = HX.STEER_RIGHT1
elif (axis_steer > 2 / 8) and (axis_steer <= 3 / 8):
steer = HX.STEER_RIGHT2
elif (axis_steer > 3 / 8) and (axis_steer <= 4 / 8):
steer = HX.STEER_RIGHT3
elif (axis_steer > 4 / 8) and (axis_steer <= 5 / 8):
steer = HX.STEER_RIGHT4
elif (axis_steer > 5 / 8) and (axis_steer <= 6 / 8):
steer = HX.STEER_RIGHT5
elif (axis_steer > 6 / 8) and (axis_steer <= 7 / 8):
steer = HX.STEER_RIGHT6
elif (axis_steer > 7 / 8) and (axis_steer <= 1):
steer = HX.STEER_RIGHT7
# Head V
if axis_head_v > 0:
head_v = int(HX.HEAD_V_CENTER - HX.HEAD_V_UP_RANGE * axis_head_v)
else:
head_v = int(HX.HEAD_V_CENTER - HX.HEAD_V_DOWN_RANGE * axis_head_v)
# Head H
if axis_head_h > 0:
head_h = int(HX.HEAD_H_CENTER - HX.HEAD_H_R_RANGE * axis_head_h)
else:
head_h = int(HX.HEAD_H_CENTER - HX.HEAD_H_L_RANGE * axis_head_h)
# Return
return (True, move, steer, head_v, head_h)

149
HXbot/HXlcd.py Executable file
View File

@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
########################################
# HXbot LCD module #
# EoF 2016 EoF@itphx.ru #
########################################
import HX
import threading
import time
import array
import struct
class HXlcdClass():
def __init__(self, i2c_bus, lock):
super(HXlcdClass, self).__init__()
self.i2c_bus = i2c_bus
self.__e = None
self.__t = None
self.lock = lock
self.online = False
self.is_running = False
self.error_count = 0
def start(self):
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.is_running = False
self.__e = None
self.__t = None
def __process(self, stopRequest):
while not stopRequest.is_set():
try:
self.__send_command(HX.COM_PING)
self.online = True
except IOError:
if self.online:
self.error_count += 1
# Too many errors
if self.error_count >= HX.LCD_ERROR_LIMIT:
self.online = False
# Delay
time.sleep(HX.LCD_DELAY)
def __sum_check(self, val, sum_):
tmp = 0x00
for b in val:
tmp ^= b
tmp ^= HX.XOR_SEQ
if tmp == sum_:
return True
else:
return False
def __read_float(self, cmd):
# Byte array
data = array.array('B', [0, 0, 0, 0])
with self.lock:
# Send command
self.__write_byte(cmd)
time.sleep(HX.LCD_RESPONSE_DELAY)
# Get bytes
data[0] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
data[1] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
data[2] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
data[3] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
# Get check sum
sum_ = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
# Check and return value
if self.__sum_check(data, sum_):
return struct.unpack('f', data)[0]
else:
return None
def __read_byte(self, cmd):
with self.lock:
# Send command
self.__write_byte(cmd)
time.sleep(HX.LCD_RESPONSE_DELAY)
# Get byte
data = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
# Get check sum
sum_ = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
# Check and return value
if data ^ HX.XOR_SEQ == sum_:
return data
else:
return None
def __write_byte(self, cmd):
cmd = (cmd << 8) | (cmd ^ HX.XOR_SEQ)
self.i2c_bus.write_word_data(HX.LCD_ADDRESS, HX.EXT_COM, cmd)
def send_cmd(self, cmd):
try:
with self.lock:
# Send command
self.__write_byte(cmd)
time.sleep(HX.LCD_RESPONSE_DELAY)
# Get response
response = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
# Return
return response
except IOError:
return HX.IOE_RSP
def __send_command(self, command):
try:
with self.lock:
self.i2c_bus.write_word_data(HX.LCD_ADDRESS, command, 0)
time.sleep(HX.LCD_RESPONSE_DELAY)
response = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
except IOError:
if self.online:
self.error_count += 1
if self.error_count >= HX.LCD_ERROR_LIMIT:
self.online = False
return HX.IOE_RSP
else:
self.error_count = 0
self.online = True
return response
return HX.NO_RSP

1
HXbot/HXlight.py Executable file
View File

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

1
HXbot/HXlog.py Executable file
View File

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

587
HXbot/HXpower.py Executable file
View File

@ -0,0 +1,587 @@
# -*- coding: utf-8 -*-
########################################
# HXbot power control module #
# EoF 2016 EoF@itphx.ru #
########################################
import HX
import threading
import time
import array
import struct
class HXpowerClass():
def __init__(self, i2c_bus, lock):
super(HXpowerClass, self).__init__()
self.i2c_bus = i2c_bus
self.__e = None
self.__t = None
self.lock = lock
# MV
self.__mv_enable_time = 0.0
self.mv_blocked = True
# HXpower data
self.online = False
self.is_running = False
self.error_count = 0
self.status = 0x000000
self.vcc = 0.0
self.vin = 0.0
self.vdc = 0.0
self.vbt = 0.0
self.vba = 0.0
self.vpf = 0.0
self.vzu = 0.0
self.abt = 0.0
self.aba = 0.0
self.ain = 0.0
self.ahx = 0.0
self.vcc_ok = False
self.vin_ok = False
self.vdc_ok = False
self.vbt_ok = False
self.vba_ok = False
self.vpf_ok = False
self.vzu_ok = False
self.abt_ok = False
self.aba_ok = False
self.ain_ok = False
self.ahx_ok = False
self.bt_enabled = False
self.ba_enabled = False
self.bt_blocked = False
self.ba_blocked = False
self.vcc_low = False
self.vcc_high = False
self.vin_low = False
self.vin_high = False
self.vdc_low = False
self.vdc_high = False
self.vbt_low = False
self.vbt_full = False
self.vba_low = False
self.vba_full = False
self.vpf_low = False
self.vpf_high = False
self.vzu_low = False
self.vzu_high = False
self.abt_low = False
self.abt_high = False
self.aba_low = False
self.aba_high = False
self.ain_low = False
self.ain_high = False
self.ahx_low = False
self.ahx_high = False
self.mv_enabled = False
self.us_enabled = False
self.in_plugged = False
self.ba_full = False
self.bt_full = False
def start(self):
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.is_running = False
self.__e = None
self.__t = None
def __process(self, stopRequest):
stat1 = 0x00
stat2 = 0x00
stat3 = 0x00
# Process loop
while not stopRequest.is_set():
try:
self.status = 0x0000
# Get status 1
tmp = self.__read_byte(HX.COM_GET_STAT1)
if tmp is not None:
stat1 = tmp << 8
else:
if self.online:
self.error_count += 1
# Get status 2
tmp = self.__read_byte(HX.COM_GET_STAT2)
if tmp is not None:
stat2 = tmp
else:
if self.online:
self.error_count += 1
# Get status 3
tmp = self.__read_byte(HX.COM_GET_STAT3)
if tmp is not None:
stat3 = tmp << 16
else:
if self.online:
self.error_count += 1
self.status |= stat1
self.status |= stat2
self.status |= stat3
# Get Voltages
tmp = self.__read_float(HX.COM_GET_VCC)
if tmp is not None:
self.vcc = tmp
tmp = self.__read_float(HX.COM_GET_VIN)
if tmp is not None:
self.vin = tmp
tmp = self.__read_float(HX.COM_GET_VDC)
if tmp is not None:
self.vdc = tmp
tmp = self.__read_float(HX.COM_GET_VBT)
if tmp is not None:
self.vbt = tmp
tmp = self.__read_float(HX.COM_GET_VBA)
if tmp is not None:
self.vba = tmp
tmp = self.__read_float(HX.COM_GET_VPF)
if tmp is not None:
self.vpf = tmp
tmp = self.__read_float(HX.COM_GET_VZU)
if tmp is not None:
self.vzu = tmp
tmp = self.__read_float(HX.COM_GET_ABT)
if tmp is not None:
self.abt = tmp
tmp = self.__read_float(HX.COM_GET_ABA)
if tmp is not None:
self.aba = tmp
tmp = self.__read_float(HX.COM_GET_AIN)
if tmp is not None:
self.ain = tmp
tmp = self.__read_float(HX.COM_GET_AHX)
if tmp is not None:
self.ahx = tmp
self.online = True
self.error_count = 0
except IOError:
if self.online:
self.error_count += 1
# Decode Status
if self.status & 0x0100:
self.vcc_ok = True
else:
self.vcc_ok = False
if self.status & 0x0200:
self.vin_ok = True
else:
self.vin_ok = False
if self.status & 0x0400:
self.vdc_ok = True
else:
self.vdc_ok = False
if self.status & 0x0800:
self.vbt_ok = True
else:
self.vbt_ok = False
if self.status & 0x1000:
self.vba_ok = True
else:
self.vba_ok = False
if self.status & 0x0010:
self.vpf_ok = True
else:
self.vpf_ok = False
if self.status & 0x0020:
self.vzu_ok = True
else:
self.vzu_ok = False
if self.status & 0x2000:
self.bt_enabled = True
else:
self.bt_enabled = False
if self.status & 0x4000:
self.ba_enabled = True
else:
self.ba_enabled = False
if self.status & 0x0040:
self.mv_enabled = True
else:
self.mv_enabled = False
if self.status & 0x0080:
self.us_enabled = True
else:
self.us_enabled = False
if self.status & 0x8000:
self.in_plugged = True
else:
self.in_plugged = False
if self.status & 0x0001:
self.bt_blocked = True
else:
self.bt_blocked = False
if self.status & 0x0002:
self.ba_blocked = True
else:
self.ba_blocked = False
if self.status & 0x0004:
self.bt_full = True
else:
self.bt_full = False
if self.status & 0x0008:
self.ba_full = True
else:
self.ba_full = False
if self.status & 0x010000:
self.abt_ok = True
else:
self.abt_ok = False
if self.status & 0x020000:
self.aba_ok = True
else:
self.aba_ok = False
if self.status & 0x040000:
self.ain_ok = True
else:
self.ain_ok = False
if self.status & 0x080000:
self.ahx_ok = True
else:
self.ahx_ok = False
# LOW | HIGH
if self.vcc < HX.VCC_LOW:
self.vcc_low = True
else:
self.vcc_low = False
if self.vcc > HX.VCC_HIGH:
self.vcc_high = True
else:
self.vcc_high = False
if self.vin < HX.VIN_LOW:
self.vin_low = True
else:
self.vin_low = False
if self.vin > HX.VIN_HIGH:
self.vin_high = True
else:
self.vin_high = False
if self.vdc < HX.VDC_LOW:
self.vdc_low = True
else:
self.vdc_low = False
if self.vdc > HX.VDC_HIGH:
self.vdc_high = True
else:
self.vdc_high = False
if self.vbt < HX.VBT_LOW:
self.vbt_low = True
else:
self.vbt_low = False
if self.vbt > HX.VBT_FULL:
self.vbt_full = True
else:
self.vbt_full = False
if self.vba < HX.VBA_LOW:
self.vba_low = True
else:
self.vba_low = False
if self.vba > HX.VBA_FULL:
self.vba_full = True
else:
self.vba_full = False
if self.vpf < HX.VPF_LOW:
self.vpf_low = True
else:
self.vpf_low = False
if self.vpf > HX.VPF_HIGH:
self.vpf_high = True
else:
self.vpf_high = False
if self.vzu < HX.VZU_LOW:
self.vzu_low = True
else:
self.vzu_low = False
if self.vzu > HX.VZU_HIGH:
self.vzu_high = True
else:
self.vzu_high = False
if self.abt < HX.ABT_LOW:
self.abt_low = True
else:
self.abt_low = False
if self.abt > HX.ABT_HIGH:
self.abt_high = True
else:
self.abt_high = False
if self.aba < HX.ABA_LOW:
self.aba_low = True
else:
self.aba_low = False
if self.aba > HX.ABA_HIGH:
self.aba_high = True
else:
self.aba_high = False
if self.ain < HX.AIN_LOW:
self.ain_low = True
else:
self.ain_low = False
if self.ain > HX.AIN_HIGH:
self.ain_high = True
else:
self.ain_high = False
if self.ahx < HX.AHX_LOW:
self.ahx_low = True
else:
self.ahx_low = False
if self.ahx > HX.AHX_HIGH:
self.ahx_high = True
else:
self.ahx_high = False
# Too many errors
if self.error_count >= HX.POWER_ERROR_LIMIT:
self.online = False
# Unblock PF
if (self.mv_enabled and time.clock() - self.__mv_enable_time >=
HX.POWER_MV_TIMEOUT / 100):
self.mv_blocked = False
# Delay
time.sleep(HX.POWER_DELAY)
def __sum_check(self, val, sum_):
tmp = 0x00
for b in val:
tmp ^= b
tmp ^= HX.XOR_SEQ
if tmp == sum_:
return True
else:
return False
def __read_float(self, cmd):
# Byte array
data = array.array('B', [0, 0, 0, 0])
with self.lock:
# Send command
self.__write_byte(cmd)
time.sleep(HX.POWER_RESPONSE_DELAY)
# Get bytes
data[0] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
data[1] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
data[2] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
data[3] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
# Get check sum
sum_ = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
# Check and return value
if self.__sum_check(data, sum_):
return struct.unpack('f', data)[0]
else:
return None
def __read_byte(self, cmd):
with self.lock:
# Send command
self.__write_byte(cmd)
time.sleep(HX.POWER_RESPONSE_DELAY)
# Get byte
data = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
# Get check sum
sum_ = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
# Check and return value
if data ^ HX.XOR_SEQ == sum_:
return data
else:
return None
def __write_byte(self, cmd):
cmd = (cmd << 8) | (cmd ^ HX.XOR_SEQ)
self.i2c_bus.write_word_data(HX.POWER_ADDRESS, HX.EXT_COM, cmd)
def send_cmd(self, cmd):
try:
with self.lock:
# Send command
self.__write_byte(cmd)
time.sleep(HX.POWER_RESPONSE_DELAY)
# Get response
response = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
# Return
return response
except IOError:
return HX.IOE_RSP
def enable_bt(self):
# Enable power from BT
if not self.bt_enabled:
# Run command
result = self.send_cmd(HX.COM_ENABLE_BT)
# Return
return result
else:
# Already enabled? OK!
return HX.OK_RSP
def disable_bt(self):
# Disable power from BT
if self.bt_enabled:
# Run command
result = self.send_cmd(HX.COM_DISABLE_BT)
# Return
return result
else:
# Already disabled? OK!
return HX.OK_RSP
def enable_us(self):
# Enable USB power
if not self.us_enabled:
# Run command
result = self.send_cmd(HX.COM_ENABLE_US)
# Return
return result
else:
# Already enabled? OK!
return HX.OK_RSP
def disable_us(self):
# Disable USB power
if self.us_enabled:
# Run command
result = self.send_cmd(HX.COM_DISABLE_US)
# Return
return result
else:
# Already disabled? OK!
return HX.OK_RSP
def enable_mv(self):
# Enable PowerFunctions and servos
if not self.mv_enabled:
# Save MV enable time
self.__mv_enable_time = time.clock()
self.mv_blocked = True
# Run command
result = self.send_cmd(HX.COM_ENABLE_MV)
# Return
return result
else:
# Already enabled? OK!
return HX.OK_RSP
def disable_mv(self):
# Disable PowerFunctions and servos
if self.mv_enabled:
# Run command
result = self.send_cmd(HX.COM_DISABLE_MV)
# Return
return result
else:
# Already disabled? OK!
return HX.OK_RSP
def enable_ba(self):
# Enable BA
if not self.ba_enabled:
# Run command
result = self.send_cmd(HX.COM_ENABLE_BA)
# Return
return result
else:
# Already enabled? OK!
return HX.OK_RSP
def disable_ba(self):
# Disable BA
if self.ba_enabled:
# Run command
result = self.send_cmd(HX.COM_DISABLE_BA)
# Return
return result
else:
# Already disabled? OK!
return HX.OK_RSP

171
HXbot/HXserver.py Executable file
View File

@ -0,0 +1,171 @@
# -*- coding: utf-8 -*-
########################################
# HXbot server module #
# EoF 2016 EoF@itphx.ru #
########################################
import HX
import threading
import socket
import sys
import struct
class HXserverClass():
def __init__(self, hxbot):
super(HXserverClass, self).__init__()
try:
self.s = socket.socket(family=socket.AF_INET,
type=socket.SOCK_DGRAM)
self.s.bind((HX.SRV_HOST, HX.SRV_PORT))
self.s.settimeout(HX.SRV_TIMEOUT)
except OSError as E:
print(E)
sys.exit()
self.hxbot = hxbot
self.hxpower = None
self.reflex = None
self.joystick = None
self.hxlcd = None
self.hxcam = None
self.__e = None
self.__t = None
self.is_running = False
def start(self):
self.hxpower = self.hxbot.hxpower
self.reflex = self.hxbot.reflex
self.joystick = self.hxbot.joystick
self.hxlcd = self.hxbot.hxlcd
self.hxcam = self.hxbot.hxcam
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.is_running = False
self.hxpower = None
self.reflex = None
self.joystick = None
self.hxlcd = None
self.hxcam = None
self.__e = None
self.__t = None
def __process(self, stopRequest):
while not stopRequest.is_set():
try:
data = self.s.recvfrom(1024)
except socket.timeout:
continue
cmd = data[0][0]
client = data[1]
if cmd == HX.SRV_CMD_GET_ALL:
self.s.sendto(self.__pack_all(), client)
else:
pass
self.s.close()
def __pack_all(self):
# INIT
pw = self.hxpower
rf = self.reflex
lc = self.hxlcd
ca = self.hxcam
if ca is not None:
ca_mcam_state = ca.mcam_state
ca_rcam_state = ca.rcam_state
ca_mmic_state = ca.mmic_state
else:
ca_mcam_state = 2
ca_rcam_state = 2
ca_mmic_state = 2
js = self.joystick
if js is not None:
js_online = js.online
else:
js_online = False
result = struct.pack(
'fffffffffff??????????????????????????????????????????????BBB',
pw.vcc,
pw.vin,
pw.vdc,
pw.vbt,
pw.vba,
pw.vpf,
pw.vzu,
pw.abt,
pw.aba,
pw.ain,
pw.ahx,
pw.online,
pw.vcc_ok,
pw.vin_ok,
pw.vdc_ok,
pw.vbt_ok,
pw.vba_ok,
pw.vpf_ok,
pw.vzu_ok,
pw.abt_ok,
pw.aba_ok,
pw.ain_ok,
pw.ahx_ok,
pw.bt_enabled,
pw.ba_enabled,
pw.bt_blocked,
pw.ba_blocked,
pw.vcc_low,
pw.vcc_high,
pw.vin_low,
pw.vin_high,
pw.vdc_low,
pw.vdc_high,
pw.vbt_low,
pw.vbt_full,
pw.vba_low,
pw.vba_full,
pw.vpf_low,
pw.vpf_high,
pw.vzu_low,
pw.vzu_high,
pw.abt_low,
pw.abt_high,
pw.aba_low,
pw.aba_high,
pw.ain_low,
pw.ain_high,
pw.ahx_low,
pw.ahx_high,
pw.mv_enabled,
pw.us_enabled,
pw.in_plugged,
pw.ba_full,
pw.bt_full,
rf.online,
js_online,
lc.online,
ca_mcam_state,
ca_rcam_state,
ca_mmic_state)
return result

1
HXbot/HXsound.py Executable file
View File

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

224
HXbot/REflex.py Executable file
View File

@ -0,0 +1,224 @@
# -*- coding: utf-8 -*-
########################################
# REflex communication module #
# EoF 2016 EoF@itphx.ru #
########################################
import threading
import time
import HX
class REflexClass():
def __init__(self, hxbot):
self.i2c_bus = hxbot.i2c_bus
self.hxbot = hxbot
self.__e = None
self.__t = None
self.lock = hxbot.reflex_lock
self.joystick = None
self.hxpower = None
self.control = HX.CONTROL_SRC_DEFAULT
self.error_count = 0
self.online = False
self.is_running = False
self.ready_to_move = False
self.last_command_time = 0.0
self.__move_float = 0
self.__steer_center = 0
# Tuple of commands for execute
self.m = (
False, # Check
HX.MOVE_FLOAT, # Move
HX.STEER_CENTER, # Steer
HX.HEAD_V_CENTER, # Head vertical orientation
HX.HEAD_H_CENTER # Head horizontal orientation
)
# Tuple with results of executions
self.s = (
HX.NO_RSP,
0,
0,
0,
0
)
def start(self):
self.joystick = self.hxbot.joystick
self.hxpower = self.hxbot.hxpower
self.__e = threading.Event()
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
self.__t.start()
self.is_running = True
def stop(self):
self.__e.set()
self.__t.join()
self.is_running = False
self.__e = None
self.__t = None
self.joystick = None
self.hxpower = None
def start_move(self):
result = HX.OK_RSP
# Enable moving
if not self.hxpower.mv_enabled:
result = self.hxpower.enable_mv()
if result != HX.OK_RSP:
return
self.ready_to_move = True
def stop_move(self, non_block=False):
result = HX.OK_RSP
# Disable moving
if self.hxpower.mv_blocked and not non_block:
return
if self.hxpower.mv_enabled:
result = self.hxpower.disable_mv()
if result != HX.OK_RSP:
return
self.ready_to_move = False
def get_temp(self):
return self.__send_command(HX.COM_GET_TEMP)
def __send_command(self, command):
try:
with self.lock:
self.i2c_bus.write_word_data(HX.REFLEX_ADDRESS, command, 0)
time.sleep(HX.REFLEX_RESPONSE_DELAY)
response = self.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
except IOError:
if self.online:
self.error_count += 1
if self.error_count >= HX.REFLEX_ERROR_LIMIT:
self.online = False
return HX.IOE_RSP
else:
self.error_count = 0
self.online = True
return response
return HX.NO_RSP
def __send_ex_command(self, flag, command):
try:
with self.lock:
self.i2c_bus.write_word_data(HX.REFLEX_ADDRESS, HX.EXT_COM,
flag << 8 | command)
time.sleep(HX.REFLEX_RESPONSE_DELAY)
response = self.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
except IOError:
if self.online:
self.error_count += 1
if self.error_count >= HX.REFLEX_ERROR_LIMIT:
self.online = False
return HX.IOE_RSP
else:
self.error_count = 0
self.online = True
return response
return HX.NO_RSP
def __get_byte(self):
try:
with self.lock:
response = self.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
except IOError:
if self.online:
self.error_count += 1
if self.error_count >= HX.REFLEX_ERROR_LIMIT:
self.online = False
return HX.IOE_RSP
else:
self.error_count = 0
self.online = True
return response
def __process(self, stopRequest):
# Process loop
while not stopRequest.is_set():
# Init cycle
have_commands = False
# Ping REflex
self.__send_command(HX.COM_PING)
# Joystick
if self.control == HX.CONTROL_SRC_JOYSTICK and self.joystick:
if self.joystick.ready:
# Joystick ready! Let's go!
if not self.ready_to_move:
self.start_move()
# Get m
self.m = self.joystick.get_m()
have_commands = self.m[0]
else:
if self.ready_to_move:
self.stop_move(True)
time.sleep(0.5)
# Execute received commands
if have_commands:
self.s = self.execute(self.m)
# No commands? Stop move...
elif (time.clock() - self.last_command_time >=
HX.REFLEX_MOVE_TIMEOUT / 100):
self.stop_move()
def execute(self, m):
# Move
if m[1] != HX.MOVE_FLOAT:
move_rsp = self.__send_ex_command(HX.MOVE_FLAG, m[1])
self.__move_float = 0
elif self.__move_float < 3:
move_rsp = self.__send_ex_command(HX.MOVE_FLAG, m[1])
self.__move_float += 1
else:
move_rsp = HX.OK_RSP
# Steer
if m[2] != HX.STEER_CENTER:
steer_rsp = self.__send_ex_command(HX.STEER_FLAG, m[2])
self.__steer_center = 0
elif self.__steer_center < 3:
steer_rsp = self.__send_ex_command(HX.STEER_FLAG, m[2])
self.__steer_center += 1
else:
steer_rsp = HX.OK_RSP
# Head vertiacal orientation
head_v_rsp = self.__send_ex_command(HX.HEAD_V_FLAG, m[3])
# Head horizontal orientation
head_h_rsp = self.__send_ex_command(HX.HEAD_H_FLAG, m[4])
# Set last command time
self.last_command_time = time.clock()
# Return execution status
return (HX.OK_RSP, move_rsp, steer_rsp, head_v_rsp, head_h_rsp)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

29
HXbot/hxbot.nja Executable file
View File

@ -0,0 +1,29 @@
{
"mainFile": "HXbot.py",
"use-tabs": false,
"venv": "",
"relatedProjects": [],
"name": "HXbot",
"license": "GNU General Public License v3",
"url": "",
"pythonPath": "/usr/bin/python3",
"preExecScript": "",
"additional_builtins": [],
"programParams": "",
"indentation": 4,
"PYTHONPATH": "",
"supported-extensions": [
".py",
".html",
".jpg",
".png",
".ui",
".css",
".json",
".js",
".ini"
],
"project-type": "Import from sources",
"postExecScript": "",
"description": "Main program of HXbot"
}

4
HXcam/audio Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
# Logitec C920 mic
# RTSP
cvlc -v 'alsa://hw:0,0' --sout '#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{sdp=rtsp://:8556/audio}'

19
HXcam/mainCam Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# Logitec C920
# 1280x800:30
# RTSP
cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15' --sout '#rtp{sdp=rtsp://:8554/video}' -v --live-caching 50
# MP4
#cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15' --sout '#http{mux=ts,dst=:8080/main.mp4}' -v --live-caching 50
# OGG
#cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15' --sout '#transcode{vcodec=theora}:http{mux=ogg,dst=:8080/main.ogg}' -v --live-caching 50
# ASF
#cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15' --sout '#http{mux=asf,dst=:8080/}' -v --live-caching 50
#v4l2-ctl --device=/dev/video1 --set-fmt-video=width=1280,height=720,pixelformat=1
#ffmpeg -r 15 -use_wallclock_as_timestamps 1 -copytb 0 -f v4l2 -vcodec h264 -i /dev/video1 -vcodec copy -f rtsp rtsp://:8554/video

5
HXcam/rearCam Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
# RPI Camera
# 1280x800:30
# RTSP
raspivid -t 0 -n -w 1280 -h 720 -fps 15 -o - | cvlc -v stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8555/video}' :demux=h264

368
HXgui/HX.py Executable file
View File

@ -0,0 +1,368 @@
# -*- coding: utf-8 -*-
########################################
# HXbot utility module #
# EoF 2016 EoF@itphx.ru #
########################################
# I2C bus
I2C_BUS_NUMBER = 1
EXT_COM = 0xAA
XOR_SEQ = 0xFF
# VAR
REFLEX_ADDRESS = 0x04
REFLEX_RESPONSE_DELAY = 0.1 # Delay to get response after send command, sec
REFLEX_ERROR_LIMIT = 5
REFLEX_MOVE_TIMEOUT = 60
# COMMANDS
# Util
COM_PING = 0x01
COM_GET_TEMP = 0x02
COM_GET_DISTANCE = 0x03
# Stop
STOP = 0x0F
# Move
MOVE_FLAG = 0x04
MOVE_FLOAT = 0x10
MOVE_FWD1 = 0x11
MOVE_FWD2 = 0x12
MOVE_FWD3 = 0x13
MOVE_FWD4 = 0x14
MOVE_FWD5 = 0x15
MOVE_FWD6 = 0x16
MOVE_FWD7 = 0x17
MOVE_BREAK = 0x18
MOVE_REV7 = 0x19
MOVE_REV6 = 0x1A
MOVE_REV5 = 0x1B
MOVE_REV4 = 0x1C
MOVE_REV3 = 0x1D
MOVE_REV2 = 0x1E
MOVE_REV1 = 0x1F
# Steering
STEER_FLAG = 0x05
STEER_CENTER = 0x20
STEER_LEFT1 = 0x21
STEER_LEFT2 = 0x22
STEER_LEFT3 = 0x23
STEER_LEFT4 = 0x24
STEER_LEFT5 = 0x25
STEER_LEFT6 = 0x26
STEER_LEFT7 = 0x27
STEER_FIX_CENTER = 0x28
STEER_RIGHT7 = 0x29
STEER_RIGHT6 = 0x2A
STEER_RIGHT5 = 0x2B
STEER_RIGHT4 = 0x2C
STEER_RIGHT3 = 0x2D
STEER_RIGHT2 = 0x2E
STEER_RIGHT1 = 0x2F
# Head
HEAD_H_FLAG = 0x30
HEAD_V_FLAG = 0x31
HEAD_H_R_RANGE = 83
HEAD_H_L_RANGE = 94
HEAD_V_UP_RANGE = 90
HEAD_V_DOWN_RANGE = 25
HEAD_H_CENTER = 83
HEAD_V_CENTER = 150
# CONTROL SOURCE
CONTROL_SRC_NONE = 0x00
CONTROL_SRC_JOYSTICK = 0x01
CONTROL_SRC_IRREMOTE = 0x02
CONTROL_SRC_SERVER = 0x03
CONTROL_SRC_DB = 0x04
CONTROL_SRC_SUB1 = 0x11
CONTROL_SRC_SUB2 = 0x12
CONTROL_SRC_SUB3 = 0x13
CONTROL_SRC_SUB4 = 0x14
CONTROL_SRC_SUB5 = 0x15
CONTROL_SRC_DEFAULT = CONTROL_SRC_JOYSTICK
# MOVE STATES
MOVE_STATE_STOP = 0x00
MOVE_STATE_MOVE = 0x01
# STATUS
STATUS_INIT = 0x00
STATUS_READY = 0x01
STATUS_RUNNING = 0x02
STATUS_STOP = 0x03
STATUS_EXIT = 0x04
# STATUS STATES
#STATUS_STATE_OK = 0x00
#STATUS_STATE_WARNING = 0x01
#STATUS_STATE_ERROR = 0x02
#STATUS_STATE_LOWBAT1 = 0x03
#STATUS_STATE_LOWBAT2 = 0x04
# JOYSTICK
JOYSTICK_PATH = '/dev/input/js0'
JOYSTICK_READY_TIMEOUT = 60
# These constants were borrowed from linux/input.h
JOYSTICK_AXIS_NAMES = {
0x00: 'x',
0x01: 'y',
0x02: 'z',
0x03: 'rx',
0x04: 'ry',
0x05: 'rz',
0x06: 'trottle',
0x07: 'rudder',
0x08: 'wheel',
0x09: 'gas',
0x0a: 'brake',
0x10: 'hat0x',
0x11: 'hat0y',
0x12: 'hat1x',
0x13: 'hat1y',
0x14: 'hat2x',
0x15: 'hat2y',
0x16: 'hat3x',
0x17: 'hat3y',
0x18: 'pressure',
0x19: 'distance',
0x1a: 'tilt_x',
0x1b: 'tilt_y',
0x1c: 'tool_width',
0x20: 'volume',
0x28: 'misc',
}
JOYSTICK_BUTTON_NAMES = {
0x120: 'trigger',
0x121: 'thumb',
0x122: 'thumb2',
0x123: 'top',
0x124: 'top2',
0x125: 'pinkie',
0x126: 'base',
0x127: 'base2',
0x128: 'base3',
0x129: 'base4',
0x12a: 'base5',
0x12b: 'base6',
0x12f: 'dead',
0x130: 'a',
0x131: 'b',
0x132: 'c',
0x133: 'x',
0x134: 'y',
0x135: 'z',
0x136: 'tl',
0x137: 'tr',
0x138: 'tl2',
0x139: 'tr2',
0x13a: 'select',
0x13b: 'start',
0x13c: 'mode',
0x13d: 'thumbl',
0x13e: 'thumbr',
0x220: 'dpad_up',
0x221: 'dpad_down',
0x222: 'dpad_left',
0x223: 'dpad_right',
# XBox 360 controller uses these codes.
0x2c0: 'dpad_left',
0x2c1: 'dpad_right',
0x2c2: 'dpad_up',
0x2c3: 'dpad_down',
}
# JOYSTICK BINDS
JOYSTICK_MOVE_AXIS = 'y'
JOYSTICK_STEER_AXIS = 'x'
JOYSTICK_HEAD_V_AXIS = 'rz'
JOYSTICK_HEAD_H_AXIS = 'z'
JOYSTICK_START_BTN_1 = 'tl2'
JOYSTICK_START_BTN_2 = 'tr2'
# HXpower
POWER_ADDRESS = 0x05
POWER_RESPONSE_DELAY = 0.05 # Delay to get response after send command, sec
POWER_DELAY = 0.3
POWER_ERROR_LIMIT = 3
POWER_PF_TIMEOUT = 60
# Commands
# VOLTMETERS
COM_GET_VIN = 0x01
COM_GET_VDC = 0x02
COM_GET_VBT = 0x03
COM_GET_VBA = 0x04
COM_GET_VIS = 0x05
COM_GET_VZU = 0x06
COM_GET_VCC = 0x07
# AMPERMETERS
COM_GET_AHX = 0x21
COM_GET_ABA = 0x22
COM_GET_AIN = 0x23
COM_GET_ADC = 0x24
# STATUS
COM_GET_STAT1 = 0x08
# 0x01 - vcc_ok
# 0x02 - vin_ok
# 0x04 - vdc_ok
# 0x08 - vbt_ok
# 0x10 - vba_ok
# 0x20 - lr_enabled
# 0x40 - ba_enabled
# 0x80 - ba_blocked
COM_GET_STAT2 = 0x09
# 0x01 - bl_powered
# 0x02 - bl_error
# 0x04 - pf_complete
# 0x08 - pf_charge
# 0x10 - vis_ok
# 0x20 - vzu_ok
# 0x40 - pf_enabled
# 0x80 - bl_enabled
COM_GET_STAT3 = 0x20
# 0x01 - ahx_ok
# 0x02 - aba_ok
# 0x04 - ain_ok
# 0x08 - adc_ok
# TEMP
COM_GET_POWER_TEMP = 0x10
VIN_MIN = 10.0
VIN_MAX = 14.0
VIN_LOW = 11.0
VIN_HIGH = 13.0
VDC_MIN = 5.0
VDC_MAX = 5.7
VDC_LOW = 5.1
VDC_HIGH = 5.5
VBT_MIN = 3.65
VBT_MAX = 4.25
VBT_LOW = 3.68
VBT_FULL = 4.1
VBA_MIN = 9.0
VBA_MAX = 12.8
VBA_LOW = 10.0
VBA_FULL = 12.4
VIS_MIN = 4.5
VIS_MAX = 5.3
VIS_LOW = 4.7
VIS_HIGH = 5.2
VZU_MIN = 5.0
VZU_MAX = 6.3
VZU_LOW = 5.2
VZU_HIGH = 6.2
VCC_MIN = 4.5
VCC_MAX = 5.3
VCC_LOW = 4.7
VCC_HIGH = 5.1
AHX_MIN = 0.3
AHX_MAX = 2.0
AHX_LOW = 0.4
AHX_HIGH = 1.2
ABA_MIN = 0.05
ABA_MAX = 2.0
ABA_LOW = 0.5
ABA_HIGH = 1.5
AIN_MIN = 0.05
AIN_MAX = 2.0
AIN_LOW = 0.1
AIN_HIGH = 1.5
ADC_MIN = 0.05
ADC_MAX = 3.0
ADC_LOW = 0.1
ADC_HIGH = 1.5
# RELAYS
COM_POWER_ON_BL = 0x11 # 17
COM_POWER_ON_PF = 0x12 # 18
COM_SWITCH_TO_IS = 0x13 # 19
COM_SWITCH_TO_IN = 0x14 # 20
COM_SHUTDOWN_BL = 0x15 # 21
COM_SHUTDOWN_PF = 0x16 # 22
COM_SWITCH_TO_LR = 0x17 # 23
COM_SWITCH_TO_BA = 0x18 # 24
COM_ENABLE_PF = 0x1B # 27
COM_DISABLE_PF = 0x1C # 28
COM_ENABLE_BL = 0x1D # 29
COM_DISABLE_BL = 0x1E # 30
# HXserver
SRV_PORT = 50306
SRV_HOST = ''
SRV_CMD_GET_ALL = 0x01
SRV_TIMEOUT = 1
SRV_MAX_ERR_COUNT = 3
# RETURN CODES
# Universal return codes
OK_RSP = 0x00
NO_RSP = 0xFF
ERR_RSP = 0x01
BLK_RSP = 0x02
CSE_RSP = 0x03
IOE_RSP = 0x04
TMO_RSP = 0x05
# HXbot modul flags
I2C_BUS_ERR = 0x0001
HXPOWER_ERR = 0x0002
REFLEX_ERR = 0x0004
SERVER_ERR = 0x0008
JOYSTICK_WRN = 0x0010
HXCAMERA_WRN = 0x0020
HXLCD_WRN = 0x0040
HXDB_WRN = 0x0080
HXLIGHT_WRN = 0x0100
HXSOUND_WRN = 0x0200
HXLOG_WRN = 0x0400
# HXlcd
LCD_ADDRESS = 0x06
LCD_ERROR_LIMIT = 5
LCD_DELAY = 1
LCD_RESPONSE_DELAY = 0.05
# HXcam
CAM_MAX_WRN_COUNT = 3
CAM_DELAY = 1.0
CAM_STATE_STP = 0
CAM_STATE_RUN = 1
CAM_STATE_WRN = 2
CAM_STATE_ERR = 3
# HXdb
DB_DELAY = 1.0
DB_HOST = 'localhost'
DB_NAME = 'hxdb'
DB_USER = 'hxdb'
DB_PASS = 'hxdbP@S$'

BIN
HXgui/HX.pyc Normal file

Binary file not shown.

724
HXgui/HXgui.py Executable file
View File

@ -0,0 +1,724 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
########################################
# HXbot GUI #
# EoF 2016 EoF@itphx.ru #
########################################
import socket
import sys
import struct
import curses
import time
import HX
import select
from curses import wrapper
class HXguiClass():
def __init__(self, stdscr):
super(HXguiClass, self).__init__()
# UDP Socket
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.settimeout(HX.SRV_TIMEOUT)
# Init color pairs
self.RED_ON_BLACK = 1
self.GREEN_ON_BLACK = 2
self.YELLOW_ON_BLACK = 3
self.BLUE_ON_BLACK = 4
self.BLACK_ON_RED = 5
curses.init_pair(self.RED_ON_BLACK, curses.COLOR_RED,
curses.COLOR_BLACK)
curses.init_pair(self.GREEN_ON_BLACK, curses.COLOR_GREEN,
curses.COLOR_BLACK)
curses.init_pair(self.YELLOW_ON_BLACK, curses.COLOR_YELLOW,
curses.COLOR_BLACK)
curses.init_pair(self.BLUE_ON_BLACK, curses.COLOR_BLUE,
curses.COLOR_BLACK)
curses.init_pair(self.BLACK_ON_RED, curses.COLOR_BLACK,
curses.COLOR_RED)
# Params
self.power_online = False
self.vcc = 0.0
self.vin = 0.0
self.vdc = 0.0
self.vbt = 0.0
self.vba = 0.0
self.vpf = 0.0
self.vzu = 0.0
self.abt = 0.0
self.aba = 0.0
self.ain = 0.0
self.ahx = 0.0
self.vcc_ok = False
self.vcc_low = False
self.vcc_high = False
self.vin_ok = False
self.vin_low = False
self.vin_high = False
self.vdc_ok = False
self.vdc_low = False
self.vdc_high = False
self.vbt_ok = False
self.vbt_low = False
self.vbt_full = False
self.vba_ok = False
self.vba_low = False
self.vba_full = False
self.vpf_ok = False
self.vpf_low = False
self.vpf_high = False
self.vzu_ok = False
self.vzu_low = False
self.vzu_high = False
self.abt_ok = False
self.abt_low = False
self.abt_high = False
self.aba_ok = False
self.aba_low = False
self.aba_high = False
self.ain_ok = False
self.ain_low = False
self.ain_high = False
self.adc_ok = False
self.adc_low = False
self.adc_high = False
self.bt_enabled = False
self.ba_enabled = False
self.mv_enabled = False
self.us_enabled = False
self.in_plugged = False
self.bt_blocked = False
self.ba_blocked = False
self.bt_full = False
self.ba_full = False
self.reflex_online = False
self.joystick_online = False
self.lcd_online = False
self.main_cam_state = 0
self.rear_cam_state = 0
self.main_mic_state = 0
self.error_count = 0
self.connected = False
# Init screen
stdscr.clear()
stdscr.refresh()
def draw_interface(self):
self.header_text = "-= HXbot console v0.4 =-"
self.footer_text = "-= EoF 2016 =-"
self.header = curses.newwin(1, curses.COLS, 0, 0)
self.header.bkgd(' ', curses.A_REVERSE)
self.header.addstr(0, (curses.COLS - len(self.header_text)) // 2,
self.header_text, curses.A_REVERSE)
self.footer = curses.newwin(1, curses.COLS, curses.LINES - 1, 0)
self.footer.bkgd(' ', curses.A_REVERSE)
self.footer.addstr(0, (curses.COLS - len(self.footer_text)) // 2,
self.footer_text, curses.A_REVERSE)
self.comline = curses.newwin(1, curses.COLS, curses.LINES - 2, 0)
self.comline.bkgd(' ', curses.A_NORMAL)
self.comline.addstr(0, 0, "COMMAND: ", curses.A_BOLD)
self.mainwin = curses.newwin(curses.LINES - 3, curses.COLS, 1, 0)
self.mainwin.border()
# Draw tables
self.mainwin.addstr(2, 3, "| Vcc | Vin | Vdc | Vbt | Vba " +
"| Vpf | Vzu |", curses.A_REVERSE)
self.mainwin.addstr(3, 3, "| | | | | " +
"| | |", curses.A_NORMAL)
self.mainwin.addstr(4, 3, "| | | | | " +
"| | |", curses.A_NORMAL)
self.mainwin.addstr(6, 3, "| Abt || Aba || Ain || Ahx |",
curses.A_REVERSE)
self.mainwin.addstr(7, 3, "| || || || |",
curses.A_NORMAL)
self.mainwin.addstr(8, 3, "| || || || |",
curses.A_NORMAL)
self.mainwin.addstr(10, 3, "| MAIN POWER || MOVE POWER |",
curses.A_REVERSE)
self.mainwin.addstr(11, 3, "| || |",
curses.A_NORMAL)
self.mainwin.addstr(12, 3, "| || |",
curses.A_NORMAL)
#self.mainwin.addstr(11, 41, "| OK |",
#curses.A_REVERSE)
#self.mainwin.addstr(12, 41, "| |",
#curses.A_NORMAL)
self.mainwin.addstr(2, 55, "| STATUS |",
curses.A_REVERSE)
self.mainwin.addstr(3, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(4, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(5, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(6, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(7, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(8, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(9, 55, "| |",
curses.A_NORMAL)
self.mainwin.addstr(6, 41, "| BT & BA |",
curses.A_REVERSE)
self.mainwin.addstr(7, 41, "| |",
curses.A_NORMAL)
self.mainwin.addstr(8, 41, "| |",
curses.A_NORMAL)
self.mainwin.addstr(9, 41, "| |",
curses.A_NORMAL)
self.mainwin.addstr(10, 41, "| |",
curses.A_NORMAL)
self.mainwin.addstr(11, 41, "| |",
curses.A_NORMAL)
# Add text windows
# Voltage states
self.vcc_st_win = curses.newwin(1, 5, 4, 5)
self.vin_st_win = curses.newwin(1, 5, 4, 12)
self.vdc_st_win = curses.newwin(1, 5, 4, 19)
self.vbt_st_win = curses.newwin(1, 5, 4, 26)
self.vba_st_win = curses.newwin(1, 5, 4, 33)
self.vpf_st_win = curses.newwin(1, 5, 4, 40)
self.vzu_st_win = curses.newwin(1, 5, 4, 47)
# Voltage values
self.vcc_win = curses.newwin(1, 5, 5, 5)
self.vin_win = curses.newwin(1, 5, 5, 12)
self.vdc_win = curses.newwin(1, 5, 5, 19)
self.vbt_win = curses.newwin(1, 5, 5, 26)
self.vba_win = curses.newwin(1, 5, 5, 33)
self.vpf_win = curses.newwin(1, 5, 5, 40)
self.vzu_win = curses.newwin(1, 5, 5, 47)
# Current states
self.abt_st_win = curses.newwin(1, 6, 8, 5)
self.aba_st_win = curses.newwin(1, 6, 8, 14)
self.ain_st_win = curses.newwin(1, 6, 8, 23)
self.ahx_st_win = curses.newwin(1, 6, 8, 32)
# Current values
self.abt_win = curses.newwin(1, 6, 9, 5)
self.aba_win = curses.newwin(1, 6, 9, 14)
self.ain_win = curses.newwin(1, 6, 9, 23)
self.ahx_win = curses.newwin(1, 6, 9, 32)
# Status
self.bt_st_win = curses.newwin(1, 14, 12, 5)
self.ba_st_win = curses.newwin(1, 14, 13, 5)
self.mv_st_win = curses.newwin(1, 14, 12, 23)
self.us_st_win = curses.newwin(1, 14, 13, 23)
# Online Status
self.pw_online_win = curses.newwin(1, 19, 4, 57)
self.rf_online_win = curses.newwin(1, 19, 5, 57)
self.js_online_win = curses.newwin(1, 19, 6, 57)
self.lc_online_win = curses.newwin(1, 19, 7, 57)
self.mc_online_win = curses.newwin(1, 19, 8, 57)
self.rc_online_win = curses.newwin(1, 19, 9, 57)
self.mm_online_win = curses.newwin(1, 19, 10, 57)
# BL & BA status
self.bt_blocked_win = curses.newwin(1, 9, 8, 43)
self.ba_blocked_win = curses.newwin(1, 9, 9, 43)
self.in_status_win = curses.newwin(1, 9, 10, 43)
self.bt_status_win = curses.newwin(1, 9, 11, 43)
self.ba_status_win = curses.newwin(1, 9, 12, 43)
# Error pad
clr = curses.color_pair(self.RED_ON_BLACK)
self.error_pad = curses.newpad(3, 20)
self.error_pad.border()
self.error_pad.addstr(1, 2, "Connection lost!", clr)
self.header.refresh()
self.footer.refresh()
self.mainwin.refresh()
def draw_data(self):
# Set voltage states
if self.vcc_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vcc_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vcc_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.vcc_st_win.addstr(0, 0, tst, clr)
self.vcc_st_win.refresh()
if self.vin_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vin_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vin_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.vin_st_win.addstr(0, 0, tst, clr)
self.vin_st_win.refresh()
if self.vdc_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vdc_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vdc_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.vdc_st_win.addstr(0, 0, tst, clr)
self.vdc_st_win.refresh()
if self.vbt_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vbt_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vbt_full:
tst = "FULL"
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.vbt_st_win.addstr(0, 0, tst, clr)
self.vbt_st_win.refresh()
if self.mv_enabled:
if self.vpf_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vpf_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vpf_high:
tst = "HIGH"
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
else:
tst = "OFF "
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.vpf_st_win.addstr(0, 0, tst, clr)
self.vpf_st_win.refresh()
if self.vba_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vba_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vba_full:
tst = "FULL"
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.vba_st_win.addstr(0, 0, tst, clr)
self.vba_st_win.refresh()
if self.mv_enabled:
if self.vzu_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.vzu_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.vzu_high:
tst = "HIGH"
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
else:
tst = "OFF "
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.vzu_st_win.addstr(0, 0, tst, clr)
self.vzu_st_win.refresh()
if self.abt_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.abt_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.abt_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.abt_st_win.addstr(0, 0, tst, clr)
self.abt_st_win.refresh()
if self.aba_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.aba_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.aba_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.aba_st_win.addstr(0, 0, tst, clr)
self.aba_st_win.refresh()
if self.ain_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.ain_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.ain_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.ain_st_win.addstr(0, 0, tst, clr)
self.ain_st_win.refresh()
if self.ahx_ok:
tst = " OK "
clr = curses.color_pair(self.GREEN_ON_BLACK)
if self.ahx_low:
tst = "LOW "
clr = curses.color_pair(self.YELLOW_ON_BLACK)
elif self.ahx_high:
tst = "HIGH"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
tst = "FAIL"
clr = curses.color_pair(self.RED_ON_BLACK)
self.ahx_st_win.addstr(0, 0, tst, clr)
self.ahx_st_win.refresh()
# Set voltage values
try:
self.vcc_win.addstr(0, 0, '{:1.2f}'.format(self.vcc),
curses.A_NORMAL)
self.vcc_win.refresh()
self.vin_win.addstr(0, 0, '{:2.1f}'.format(self.vin),
curses.A_NORMAL)
self.vin_win.refresh()
self.vdc_win.addstr(0, 0, '{:1.2f}'.format(self.vdc),
curses.A_NORMAL)
self.vdc_win.refresh()
self.vbt_win.addstr(0, 0, '{:1.2f}'.format(self.vbt),
curses.A_NORMAL)
self.vbt_win.refresh()
self.vba_win.addstr(0, 0, '{:2.1f}'.format(self.vba),
curses.A_NORMAL)
self.vba_win.refresh()
self.vpf_win.addstr(0, 0, '{:1.2f}'.format(self.vpf),
curses.A_NORMAL)
self.vpf_win.refresh()
self.vzu_win.addstr(0, 0, '{:1.2f}'.format(self.vzu),
curses.A_NORMAL)
self.vzu_win.refresh()
self.abt_win.addstr(0, 0, '{:2.2f}'.format(self.abt),
curses.A_NORMAL)
self.abt_win.refresh()
self.aba_win.addstr(0, 0, '{:2.2f}'.format(self.aba),
curses.A_NORMAL)
self.aba_win.refresh()
self.ain_win.addstr(0, 0, '{:2.2f}'.format(self.ain),
curses.A_NORMAL)
self.ain_win.refresh()
self.ahx_win.addstr(0, 0, '{:2.2f}'.format(self.ahx),
curses.A_NORMAL)
self.ahx_win.refresh()
except curses.error:
#comline.addstr(0, 0, str(vba), curses.A_NORMAL)
#comline.refresh()
pass
# Set status
if self.bt_enabled:
tst = "BT Enabled "
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "BT Disabled"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
self.bt_st_win.addstr(0, 0, tst, clr)
self.bt_st_win.refresh()
if self.ba_enabled:
tst = "BA Enabled "
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "BA Disabled"
clr = curses.color_pair(self.YELLOW_ON_BLACK)
self.ba_st_win.addstr(0, 0, tst, clr)
self.ba_st_win.refresh()
if self.mv_enabled:
tst = "MV Enabled "
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "MV Disabled"
clr = curses.color_pair(self.RED_ON_BLACK)
self.mv_st_win.addstr(0, 0, tst, clr)
self.mv_st_win.refresh()
if self.us_enabled:
tst = "US Enabled "
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "US Disabled"
clr = curses.color_pair(self.RED_ON_BLACK)
self.us_st_win.addstr(0, 0, tst, clr)
self.us_st_win.refresh()
# Set online status
tst = "HXpower"
if self.power_online:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.RED_ON_BLACK)
self.pw_online_win.addstr(0, 0, tst, clr)
self.pw_online_win.refresh()
tst = "REflex"
if self.reflex_online:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.RED_ON_BLACK)
self.rf_online_win.addstr(0, 0, tst, clr)
self.rf_online_win.refresh()
tst = "Joystick"
if self.joystick_online:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.js_online_win.addstr(0, 0, tst, clr)
self.js_online_win.refresh()
tst = "Display"
if self.lcd_online:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.lc_online_win.addstr(0, 0, tst, clr)
self.lc_online_win.refresh()
tst = "Main camera"
if self.main_cam_state == HX.CAM_STATE_RUN:
clr = curses.color_pair(self.GREEN_ON_BLACK)
elif self.main_cam_state == HX.CAM_STATE_STP:
clr = curses.color_pair(self.BLUE_ON_BLACK)
elif self.main_cam_state == HX.CAM_STATE_WRN:
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
clr = curses.color_pair(self.RED_ON_BLACK)
self.mc_online_win.addstr(0, 0, tst, clr)
self.mc_online_win.refresh()
tst = "Rear camera"
if self.rear_cam_state == HX.CAM_STATE_RUN:
clr = curses.color_pair(self.GREEN_ON_BLACK)
elif self.rear_cam_state == HX.CAM_STATE_STP:
clr = curses.color_pair(self.BLUE_ON_BLACK)
elif self.rear_cam_state == HX.CAM_STATE_WRN:
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
clr = curses.color_pair(self.RED_ON_BLACK)
self.rc_online_win.addstr(0, 0, tst, clr)
self.rc_online_win.refresh()
tst = "Main mic"
if self.main_mic_state == HX.CAM_STATE_RUN:
clr = curses.color_pair(self.GREEN_ON_BLACK)
elif self.main_mic_state == HX.CAM_STATE_STP:
clr = curses.color_pair(self.BLUE_ON_BLACK)
elif self.main_mic_state == HX.CAM_STATE_WRN:
clr = curses.color_pair(self.YELLOW_ON_BLACK)
else:
clr = curses.color_pair(self.RED_ON_BLACK)
self.mm_online_win.addstr(0, 0, tst, clr)
self.mm_online_win.refresh()
# Set EX & BA status
tst = "BT block"
if self.bt_blocked:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.bt_blocked_win.addstr(0, 0, tst, clr)
self.bt_blocked_win.refresh()
tst = "BA block"
if self.ba_blocked:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.ba_blocked_win.addstr(0, 0, tst, clr)
self.ba_blocked_win.refresh()
tst = "IN plugg"
if self.in_plugged:
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.in_status_win.addstr(0, 0, tst, clr)
self.in_status_win.refresh()
#if self.bt_charge:
#tst = "BT chrg"
#clr = curses.color_pair(self.YELLOW_ON_BLACK)
if self.bt_full:
tst = "BT full"
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "BT chrg"
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.bt_status_win.addstr(0, 0, tst, clr)
self.bt_status_win.refresh()
#if self.ba_charge:
#tst = "BA chrg"
#clr = curses.color_pair(self.YELLOW_ON_BLACK)
if self.ba_full:
tst = "BA full"
clr = curses.color_pair(self.GREEN_ON_BLACK)
else:
tst = "BA chrg"
clr = curses.color_pair(self.BLUE_ON_BLACK)
self.ba_status_win.addstr(0, 0, tst, clr)
self.ba_status_win.refresh()
def get_data(self):
# Get values
HOST, PORT = "localhost", HX.SRV_PORT
self.s.sendto(struct.pack('B', HX.SRV_CMD_GET_ALL), (HOST, PORT))
try:
data = self.s.recv(1024)
except socket.timeout:
if self.error_count < HX.SRV_MAX_ERR_COUNT:
self.error_count += 1
else:
self.connected = False
return
self.error_count = 0
self.connected = True
self.vcc, self.vin, self.vdc, self.vbt, self.vba, self.vpf, self.vzu, \
self.abt, self.aba, self.ain, self.ahx, \
self.power_online, \
self.vcc_ok, self.vin_ok, self.vdc_ok, self.vbt_ok, self.vba_ok, \
self.vpf_ok, self.vzu_ok, \
self.abt_ok, self.aba_ok, self.ain_ok, self.ahx_ok, \
self.bt_enabled, self.ba_enabled, self.bt_blocked, self.ba_blocked, \
self.vcc_low, self.vcc_high, self.vin_low, self.vin_high, \
self.vdc_low, self.vdc_high, self.vbt_low, self.vbt_full, \
self.vba_low, self.vba_full, self.vpf_low, self.vpf_high, \
self.vzu_low, self.vzu_high, \
self.abt_low, self.abt_high, self.aba_low, self.aba_high, \
self.ain_low, self.ain_high, self.ahx_low, self.ahx_high, \
self.mv_enabled, self.us_enabled, self.in_plugged, \
self.ba_full, self.bt_full, self.reflex_online, \
self.joystick_online, self.lcd_online, \
self.main_cam_state, self.rear_cam_state, self.main_mic_state = \
struct.unpack(
'fffffffffff??????????????????????????????????????????????BBB',
data)
def execute(self):
self.draw_interface()
redrawed = False
while True:
# Get values
self.get_data()
self.draw_data()
if not self.connected:
self.error_pad.refresh(0, 0, 10, 30, 13, 50)
redrawed = False
else:
if not redrawed:
self.mainwin.redrawwin()
self.mainwin.refresh()
redrawed = True
self.comline.refresh()
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
key = self.comline.getkey()
if key.upper() == 'Q':
break
time.sleep(0.2)
def main(stdscr):
HXgui = HXguiClass(stdscr)
HXgui.execute()
sys.exit()
# GENERAL PROGRAM
if __name__ == "__main__":
# Setup
stdscr = curses.initscr()
curses.start_color()
curses.noecho()
curses.cbreak()
stdscr.keypad(True)
# Start main function
wrapper(main)
# Cleanup
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
curses.endwin()

Binary file not shown.

Binary file not shown.

7
HXgui/hxgui.nja Executable file
View File

@ -0,0 +1,7 @@
{
"venv": "",
"project-type": "Import from sources",
"name": "HXgui",
"license": "GNU General Public License v3",
"description": "HXbot GUI"
}

339
HXlcd/HXlcd.ino Normal file
View File

@ -0,0 +1,339 @@
/////////////////////////////////////////
// HXbot HXlcd firmware /
// EoF 2016 EoF@itphx.ru /
/////////////////////////////////////////
#include <Wire.h>
#include <TroykaDHT11.h>
#include <LiquidCrystal.h>
// DEBUG
#define DEBUG 1
// DEFINE
#define SLAVE_ADDRESS 0x06
#define XOR_SEQ 0xFF
#define EXT_COM 0xAA
#define R_LED 10
#define G_LED 9
#define B_LED 11
#define L_BTN A3
#define C_BTN A2
#define R_BTN A1
#define RED_PIN 10
#define GRN_PIN 9
#define LCD_BL 3
// Sensors
#define LIGHT A6
#define LOUD A7
#define TEMP A0
#define BUZZ 13
#define FREE 12
#define LED_PIN 13
#define DELAY1 2000
#define DELAY2 500
// COMMANDS
// Util
#define COM_PING 0x01
#define COM_GET_TEMP 0x02
// Response
#define OK_RSP 0x00
#define NO_RSP 0xFF
#define ERR_RSP 0x01
#define BLK_RSP 0x02
#define CSE_RSP 0x03
#define IOE_RSP 0x04
#define TMO_RSP 0x05
// VAR
LiquidCrystal lcd(2, 4, 5, 6, 7, 8);
DHT11 dht(TEMP);
// эту константу (typVbg) необходимо откалибровать индивидуально
const float typVbg = 1.08; // 1.0 -- 1.2
byte autoresponse = 0;
byte cmd = 0;
byte flg = 0;
byte ext = 0;
int temp, hum;
void setup() {
if (DEBUG) {
Serial.println("GO!");
Serial.begin(9600);
}
// Initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(answer);
// put your setup code here, to run once:
pinMode(LED_PIN, OUTPUT);
pinMode(RED_PIN, OUTPUT);
//digitalWrite(RED_PIN, LOW);
pinMode(GRN_PIN, OUTPUT);
//digitalWrite(GRN_PIN, LOW);
pinMode(R_LED, OUTPUT);
pinMode(G_LED, OUTPUT);
pinMode(B_LED, OUTPUT);
pinMode(LCD_BL, OUTPUT);
pinMode(L_BTN,INPUT_PULLUP);
pinMode(C_BTN,INPUT_PULLUP);
pinMode(R_BTN,INPUT_PULLUP);
pinMode(LIGHT, INPUT);
pinMode(LOUD, INPUT);
pinMode(FREE, INPUT);
pinMode(BUZZ, OUTPUT);
randomSeed(millis());
analogReference(DEFAULT);
lcd.begin(16, 2);
analogWrite(LCD_BL, 255);
lcd.print("Hello world!");
dht.begin();
delay(2000);
lcd.clear();
}
void loop() {
if (digitalRead(FREE) == HIGH) {
analogWrite(GRN_PIN, 128);
}
else {
analogWrite(GRN_PIN, 0);
}
displayALL();
if (DEBUG) {
Serial.print("Vcc: ");
Serial.println(readvcc());
}
delay(500);
}
void rgb_control() {
//int tmp1;
//tmp1 = Read(L_BTN);
if (digitalRead(L_BTN) == LOW) {
analogWrite(R_LED, 255);
//Serial.println(analogRead(L_BTN));
}
else {
analogWrite(R_LED,0);
}
if (digitalRead(C_BTN) == LOW) {
analogWrite(G_LED, 255);
}
else {
analogWrite(G_LED,0);
}
if (digitalRead(R_BTN) == LOW) {
analogWrite(B_LED, 255);
}
else {
analogWrite(B_LED,0);
}
}
void displayTH() {
int result;
result = dht.read();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp:");
lcd.setCursor(0, 1);
lcd.print("Hum:");
if (result == DHT_OK) {
lcd.setCursor(6, 0);
lcd.print(dht.getTemperatureC());
lcd.print(" C");
lcd.setCursor(6, 1);
lcd.print(dht.getHumidity());
lcd.print(" %");
}
else {
lcd.setCursor(6, 0);
lcd.print("ERROR");
lcd.setCursor(6, 1);
lcd.print("ERROR");
}
}
void displayLL() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Light:");
lcd.setCursor(0, 1);
lcd.print("Loud:");
lcd.setCursor(8, 0);
lcd.print(analogRead(LIGHT));
lcd.setCursor(8, 1);
lcd.print(analogRead(LOUD));
}
void displayALL() {
int result;
result = dht.read();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Li:");
lcd.setCursor(0, 1);
lcd.print("Lo:");
lcd.setCursor(4, 0);
lcd.print(analogRead(LIGHT));
lcd.setCursor(4, 1);
lcd.print(analogRead(LOUD));
lcd.setCursor(9, 0);
lcd.print("T:");
lcd.setCursor(9, 1);
lcd.print("H:");
if (result == DHT_OK) {
lcd.setCursor(11, 0);
lcd.print(dht.getTemperatureC());
lcd.print("C");
lcd.setCursor(11, 1);
lcd.print(dht.getHumidity());
lcd.print(" %");
}
else {
lcd.setCursor(11, 0);
lcd.print("ERR");
lcd.setCursor(11, 1);
lcd.print("ERR");
}
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
// Get command
cmd = Wire.read();
if (cmd == EXT_COM && byteCount == 3) {
flg = 0x00;
ext = 0x00;
if (Wire.available()) ext = Wire.read();
if (Wire.available()) flg = Wire.read();
}
else {
// Cleanup I2C bus
while(Wire.available()) {
ext = Wire.read();
}
}
switch (cmd) {
case COM_PING:
autoresponse = OK_RSP;
blink_red();
break;
case COM_GET_TEMP:
autoresponse = getInternalTemp();
break;
default:
autoresponse = ERR_RSP;
break;
}
}
}
// Callback for sending data
void answer() {
Wire.write(autoresponse);
}
void red_on() {
digitalWrite(RED_PIN, HIGH);
}
void red_off() {
digitalWrite(RED_PIN, LOW);
}
void blink_red() {
red_on();
delay(100);
red_off();
}
// Get the internal temperature of the arduino
double getInternalTemp(void) {
unsigned int wADC;
double t;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
while (bit_is_set(ADCSRA,ADSC));
wADC = ADCW;
t = (wADC - 324.31 ) / 1.22;
return (t);
}
float readvcc() {
byte i;
float tmp = 0.0;
// Read 1.1V reference against Avcc
// set the reference to vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
// works on an Arduino 168 or 328
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(3); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
tmp = (high<<8) | low;
tmp = (typVbg * 1023.0) / tmp;
return tmp;
}

16
HXlcd2/HXlcd2.h Normal file
View File

@ -0,0 +1,16 @@
#define WHITE 0xFFFF
#define BLACK 0x0000
#define GRAY 0x7BEF
#define DGRAY 0x2124
#define BLUE 0x051C
#define LBLUE 0x96BC
#define DBLUE 0x0311
#define YELLOW 0xFF60
#define LYELLOW 0xFFAD
#define DYELLOW 0xBD80
#define SCR_MAX 5
#define SCR1_MAX 5
#define BTN_TIMEOUT 500

690
HXlcd2/HXlcd2.ino Normal file
View File

@ -0,0 +1,690 @@
/////////////////////////////////////////
// HXbot HXlcd firmware /
// EoF 2016 EoF@itphx.ru /
/////////////////////////////////////////
#include <Wire.h>
#include <TroykaDHT11.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include "HXlcd2.h"
// DEBUG
#define DEBUG 1
// DEFINE
#define SLAVE_ADDRESS 0x06
#define XOR_SEQ 0xFF
#define EXT_COM 0xAA
#define R_LED 10
#define G_LED 9
#define B_LED 11
#define L_BTN A3
#define C_BTN A2
#define R_BTN A1
//clk 4, din 5, dc 6, cs 7, rst 8
#define TFT_BL 3
#define TFT_SCLK 4
#define TFT_MOSI 5
#define TFT_DC 6
#define TFT_CS 7
#define TFT_RST 8
// Sensors
#define LIGHT A6
#define LOUD A7
#define TEMP A0
#define BUZZ 13
#define FREE 12
#define LED_PIN 13
#define DELAY1 2000
#define DELAY2 500
// COMMANDS
// Util
#define COM_PING 0x01
#define COM_GET_TEMP 0x02
// Response
#define OK_RSP 0x00
#define NO_RSP 0xFF
#define ERR_RSP 0x01
#define BLK_RSP 0x02
#define CSE_RSP 0x03
#define IOE_RSP 0x04
#define TMO_RSP 0x05
// VAR
DHT11 dht(TEMP);
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
// эту константу (typVbg) необходимо откалибровать индивидуально
const float typVbg = 1.08; // 1.0 -- 1.2
byte autoresponse = 0;
byte cmd = 0;
byte flg = 0;
byte ext = 0;
int temp, hum;
float p = 3.1415926;
float vcc;
bool l_pressed = false, c_pressed = false, r_pressed = false;
bool menu_drawed = false;
byte screen = 0, line = 1;
unsigned long t;
void setup() {
if (DEBUG) {
Serial.begin(9600);
Serial.println("GO!");
}
// Initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(answer);
// put your setup code here, to run once:
pinMode(LED_PIN, OUTPUT);
pinMode(R_LED, OUTPUT);
pinMode(G_LED, OUTPUT);
pinMode(B_LED, OUTPUT);
pinMode(TFT_BL, OUTPUT);
pinMode(L_BTN, INPUT_PULLUP);
pinMode(C_BTN, INPUT_PULLUP);
pinMode(R_BTN, INPUT_PULLUP);
pinMode(LIGHT, INPUT);
pinMode(LOUD, INPUT);
pinMode(FREE, INPUT);
pinMode(BUZZ, OUTPUT);
randomSeed(millis());
analogReference(DEFAULT);
// Use this initializer if you're using a 1.8" TFT
tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
tft.fillScreen(ST7735_BLACK);
tft.drawRect(0, 0, 128, 160, ST7735_GREEN);
tft.drawRect(1, 1, 126, 158, ST7735_WHITE);
drawL();
drawC();
drawR();
analogWrite(TFT_BL, 255);
dht.begin();
}
void loop() {
if (digitalRead(FREE) == HIGH) {
analogWrite(G_LED, 128);
}
else {
analogWrite(G_LED, 0);
}
// if (DEBUG) {
// Serial.println(r_pressed);
// Serial.println(c_pressed);
// Serial.println(l_pressed);
// }
readButtons();
drawMenu();
//displayALL();
}
void drawMenu() {
if (millis() - t < BTN_TIMEOUT) return;
if (screen == 0) {
if (l_pressed) {
line++;
if (line > SCR1_MAX) line = 1;
drawPointer();
t = millis();
}
if (r_pressed) {
line--;
if (line < 1) line = SCR1_MAX;
drawPointer();
t = millis();
}
if (! menu_drawed) {
tft.setTextSize(1);
tft.setCursor(52, 8);
tft.print("MAIN");
tft.setTextSize(1);
tft.setCursor(20, 20);
tft.print("HXbot");
tft.setCursor(20, 30);
tft.print("REflex");
tft.setCursor(20, 40);
tft.print("HXpower");
tft.setCursor(20, 50);
tft.print("HXlcd");
tft.setCursor(20, 60);
tft.print("HXcamera");
drawPointer();
menu_drawed = true;
}
if (c_pressed) {
screen = line;
line = 0;
clearMenu();
t = millis();
return;
}
}
if (screen == 1) {
if (! menu_drawed) {
tft.setTextSize(1);
tft.setCursor(49, 8);
tft.print("HXbot");
tft.setTextSize(1);
tft.setCursor(52, 130);
tft.print("back");
drawPointer();
menu_drawed = true;
}
if (c_pressed) {
screen = 0;
line = 1;
clearMenu();
t = millis();
return;
}
}
if (screen == 2) {
if (! menu_drawed) {
tft.setTextSize(1);
tft.setCursor(49, 8);
tft.print("REflex");
tft.setTextSize(1);
tft.setCursor(52, 130);
tft.print("back");
drawPointer();
menu_drawed = true;
}
if (c_pressed) {
screen = 0;
line = 1;
clearMenu();
t = millis();
return;
}
}
if (screen == 3) {
if (! menu_drawed) {
tft.setTextSize(1);
tft.setCursor(49, 8);
tft.print("HXpower");
tft.setTextSize(1);
tft.setCursor(52, 130);
tft.print("back");
drawPointer();
menu_drawed = true;
}
if (c_pressed) {
screen = 0;
line = 1;
clearMenu();
t = millis();
return;
}
}
if (screen == 4) {
if (! menu_drawed) {
tft.setTextSize(1);
tft.setCursor(49, 8);
tft.print("HXlcd");
tft.setTextSize(1);
tft.setCursor(52, 130);
tft.print("back");
drawPointer();
menu_drawed = true;
}
if (c_pressed) {
screen = 0;
line = 1;
clearMenu();
t = millis();
return;
}
}
if (screen == 5) {
if (! menu_drawed) {
tft.setTextSize(1);
tft.setCursor(49, 8);
tft.print("HXcamera");
tft.setTextSize(1);
tft.setCursor(52, 130);
tft.print("back");
drawPointer();
menu_drawed = true;
}
if (c_pressed) {
screen = 0;
line = 1;
clearMenu();
t = millis();
return;
}
}
}
void clearMenu() {
tft.fillRect(2, 2, 123, 140, BLACK);
menu_drawed = false;
}
void drawPointer() {
byte x1, y1, x2, y2, x3, y3;
if (line != 0) {
x1 = 10;
y1 = 11 + line * 10;
x2 = 10;
y2 = 15 + line * 10;
x3 = 15;
y3 = 13 + line * 10;
}
else {
x1 = 42;
y1 = 131;
x2 = 42;
y2 = 135;
x3 = 47;
y3 = 133;
}
tft.fillRect(10, 20, 6, 100, BLACK);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, WHITE);
}
void displayALL() {
// Vcc
vcc = readvcc();
tft.setCursor(10, 10);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print("Vcc=");
if (vcc < 4.8 || vcc > 5.2)
tft.setTextColor(ST7735_RED, ST7735_BLACK);
else
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print(vcc);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print(" V ");
// Light
tft.setCursor(10, 20);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print("Lightness=");
tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
tft.print(analogRead(LIGHT));
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print(" UE ");
// Loud
tft.setCursor(10, 30);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print("Loud=");
tft.setTextColor(ST7735_MAGENTA, ST7735_BLACK);
tft.print(analogRead(LOUD));
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print(" UE ");
// TH
int result;
result = dht.read();
tft.setCursor(10, 40);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print("Temp=");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
if (result == DHT_OK) tft.print(dht.getTemperatureC()); else tft.print("ERR");
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print(" C ");
tft.setCursor(10, 50);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print("Hum=");
tft.setTextColor(ST7735_BLUE, ST7735_BLACK);
if (result == DHT_OK) tft.print(dht.getHumidity()); else tft.print("ERR");
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.print(" % ");
}
void readButtons() {
if ((digitalRead(L_BTN) == LOW) && ! l_pressed) {
l_pressed = true;
drawL();
}
else {
if ((digitalRead(L_BTN) == HIGH) && l_pressed) {
l_pressed = false;
drawL();
}
}
if ((digitalRead(C_BTN) == LOW) && ! c_pressed) {
c_pressed = true;
drawC();
}
else {
if ((digitalRead(C_BTN) == HIGH) && c_pressed) {
c_pressed = false;
drawC();
}
}
if ((digitalRead(R_BTN) == LOW) && ! r_pressed) {
r_pressed = true;
drawR();
}
else {
if ((digitalRead(R_BTN) == HIGH) && r_pressed) {
r_pressed = false;
drawR();
}
}
}
void drawL() {
tft.fillRoundRect(4, 145, 37, 12, 3, YELLOW);
if (! l_pressed) {
tft.drawRoundRect(4, 145, 37, 12, 3, LYELLOW);
tft.drawLine(6, 156, 38, 156, DYELLOW);
tft.drawLine(40, 147, 40, 154, DYELLOW);
tft.drawPixel(5, 155, DYELLOW);
tft.drawPixel(39, 155, DYELLOW);
tft.fillTriangle(15, 147, 29, 147, 22, 154, GRAY);
tft.drawTriangle(15, 147, 29, 147, 22, 154, DGRAY);
}
else {
tft.drawRoundRect(4, 145, 37, 12, 3, DYELLOW);
tft.drawLine(6, 156, 38, 156, LYELLOW);
tft.drawLine(40, 147, 40, 154, LYELLOW);
tft.drawPixel(5, 155, LYELLOW);
tft.drawPixel(39, 155, LYELLOW);
tft.fillTriangle(15, 147, 29, 147, 22, 154, WHITE);
tft.drawTriangle(15, 147, 29, 147, 22, 154, DGRAY);
}
}
void drawC() {
tft.fillRoundRect(44, 144, 40, 12, 3, BLUE);
if (! c_pressed) {
tft.drawRoundRect(44, 144, 40, 12, 3, LBLUE);
tft.drawLine(46, 155, 81, 155, DBLUE);
tft.drawLine(83, 146, 83, 153, DBLUE);
tft.drawPixel(45, 154, DBLUE);
tft.drawPixel(82, 154, DBLUE);
tft.fillRoundRect(60, 146, 8, 8, 3, GRAY);
tft.drawRoundRect(60, 146, 8, 8, 3, DGRAY);
}
else {
tft.drawRoundRect(44, 144, 40, 12, 3, DBLUE);
tft.drawLine(46, 155, 81, 155, LBLUE);
tft.drawLine(83, 146, 83, 153, LBLUE);
tft.drawPixel(45, 154, LBLUE);
tft.drawPixel(82, 154, LBLUE);
tft.fillRoundRect(60, 146, 8, 8, 3, WHITE);
tft.drawRoundRect(60, 146, 8, 8, 3, DGRAY);
}
}
void drawR() {
tft.fillRoundRect(86, 145, 37, 12, 3, YELLOW);
if (! r_pressed) {
tft.drawRoundRect(86, 145, 37, 12, 3, LYELLOW);
tft.drawLine(88, 156, 120, 156, DYELLOW);
tft.drawLine(122, 147, 122, 154, DYELLOW);
tft.drawPixel(87, 155, DYELLOW);
tft.drawPixel(121, 155, DYELLOW);
tft.fillTriangle(97, 154, 111, 154, 104, 147, GRAY);
tft.drawTriangle(97, 154, 111, 154, 104, 147, DGRAY);
}
else {
tft.drawRoundRect(86, 145, 37, 12, 3, DYELLOW);
tft.drawLine(88, 156, 120, 156, LYELLOW);
tft.drawLine(122, 147, 122, 154, LYELLOW);
tft.drawPixel(87, 155, LYELLOW);
tft.drawPixel(121, 155, LYELLOW);
tft.fillTriangle(97, 154, 111, 154, 104, 147, WHITE);
tft.drawTriangle(97, 154, 111, 154, 104, 147, DGRAY);
}
}
void rgb_control() {
//int tmp1;
//tmp1 = Read(L_BTN);
if (digitalRead(L_BTN) == LOW) {
analogWrite(R_LED, 255);
//Serial.println(analogRead(L_BTN));
}
else {
analogWrite(R_LED,0);
}
if (digitalRead(C_BTN) == LOW) {
analogWrite(G_LED, 255);
}
else {
analogWrite(G_LED,0);
}
if (digitalRead(R_BTN) == LOW) {
analogWrite(B_LED, 255);
}
else {
analogWrite(B_LED,0);
}
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
// Get command
cmd = Wire.read();
if (cmd == EXT_COM && byteCount == 3) {
flg = 0x00;
ext = 0x00;
if (Wire.available()) ext = Wire.read();
if (Wire.available()) flg = Wire.read();
}
else {
// Cleanup I2C bus
while(Wire.available()) {
ext = Wire.read();
}
}
switch (cmd) {
case COM_PING:
autoresponse = OK_RSP;
blink_red();
break;
case COM_GET_TEMP:
autoresponse = getInternalTemp();
break;
default:
autoresponse = ERR_RSP;
break;
}
}
}
// Callback for sending data
void answer() {
Wire.write(autoresponse);
}
void blink_red() {
digitalWrite(R_LED, HIGH);
delay(100);
digitalWrite(R_LED, LOW);
}
// Get the internal temperature of the arduino
double getInternalTemp(void) {
unsigned int wADC;
double t;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
while (bit_is_set(ADCSRA,ADSC));
wADC = ADCW;
t = (wADC - 324.31 ) / 1.22;
return (t);
}
float readvcc() {
float tmp = 0.0;
// Read 1.1V reference against Avcc
// set the reference to vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
// works on an Arduino 168 or 328
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(3); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
tmp = (high<<8) | low;
tmp = (typVbg * 1023.0) / tmp;
return tmp;
}
void tftPrintTest() {
tft.setTextWrap(false);
tft.fillScreen(ST7735_GREEN);
tft.setCursor(0, 30);
tft.setTextColor(ST7735_RED);
tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ST7735_YELLOW);
tft.setTextSize(2);
tft.println("Hello World!");
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(3);
tft.println("Hello World!");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(4);
tft.print(1234.567);
delay(1500);
tft.setCursor(0, 0);
tft.fillScreen(ST7735_BLACK);
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(0);
tft.println("Hello World!");
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN);
tft.print(p, 6);
tft.println(" Want pi?");
tft.println(" ");
tft.print(8675309, HEX); // print 8,675,309 out in HEX!
tft.println(" Print HEX!");
tft.println(" ");
tft.setTextColor(ST7735_WHITE);
tft.println("Sketch has been");
tft.println("running for: ");
tft.setTextColor(ST7735_MAGENTA);
tft.print(millis() / 1000);
tft.setTextColor(ST7735_WHITE);
tft.print(" seconds.");
}
void tftTest() {
//
tft.fillScreen(ST7735_BLACK);
tft.drawRect(0, 0, 128, 160, ST7735_GREEN);
tft.drawRect(1, 1, 126, 158, ST7735_WHITE);
// Smile
tft.fillCircle(64, 80, 40, ST7735_YELLOW);
//tft.drawCircle(64, 80, 40, ST7735_BLUE);
tft.fillRoundRect(45, 63, 10, 15, 3, ST7735_BLACK);
tft.fillRoundRect(73, 63, 10, 15, 3, ST7735_BLACK);
tft.fillTriangle(50, 95, 78, 95, 70, 105, ST7735_BLACK);
tft.setCursor(33, 132);
tft.setTextColor(ST7735_YELLOW);
tft.setTextSize(2);
tft.print("HELLO!");
// for (byte i = 1; i <= 31; i++) {
// tft.drawRect(i * 2, i * 3, 128 - i * 4, 160 - i * 5, ST7735_WHITE);
// delay(100);
// //tft.drawRect(i * 2, i * 2, 128 - i * 4, 160 - i * 4, ST7735_BLACK);
// }
}

824
HXpower/HXpower.ino Executable file
View File

@ -0,0 +1,824 @@
/////////////////////////////////////////
// HXbot HXpower firmware /
// EoF 2016 EoF@itphx.ru /
/////////////////////////////////////////
#include <Wire.h>
// DEBUG
#define DEBUG 0
// DEFINE
#define SLAVE_ADDRESS 0x05
#define XOR_SEQ 0xFF
#define EXT_COM 0xAA
#define VIN_PIN 0
#define VDC_PIN 1
#define VBT_PIN 2
#define VBA_PIN 3
#define R_BL 7
#define R_PF 6
#define R_HX 5
#define R_IS 4
#define BL_RED_PIN 8
#define BL_GRN_PIN 9
#define BTN_PIN 2
#define LED_PIN 3
#define REP_COUNT 5
#define TIMEOUT 5000
// COMMANDS
// VOLTMETERS
#define COM_GET_VIN 0x01
#define COM_GET_VDC 0x02
#define COM_GET_VBT 0x03
#define COM_GET_VBA 0x04
#define COM_GET_VCC 0x07
// TEMP
#define COM_GET_TEMP 0x06
// STATUS
#define COM_GET_STAT1 0x08
#define COM_GET_STAT2 0x09
// RELAYS
#define COM_POWER_ON_BL 0x11 // 17
#define COM_POWER_ON_PF 0x12 // 18
#define COM_SWITCH_TO_IS 0x13 // 19
#define COM_SWITCH_TO_IN 0x14 // 20
#define COM_SHUTDOWN_BL 0x15 // 21
#define COM_SHUTDOWN_PF 0x16 // 22
#define COM_SWITCH_TO_LR 0x17 // 23
#define COM_SWITCH_TO_BA 0x18 // 24
#define COM_ENABLE_PF 0x1B // 27
#define COM_DISABLE_PF 0x1C // 28
#define COM_ENABLE_BL 0x1D // 29
#define COM_DISABLE_BL 0x1E // 30
#define OK_RSP 0x00
#define NO_RSP 0xFF
#define ERR_RSP 0x01
#define BLK_RSP 0x02
#define CSE_RSP 0x03
#define IOE_RSP 0x04
#define TMO_RSP 0x05
// CONST
#define DELAY_TIME 900
#define BA_TIMEOUT 3000
#define BA_BLOCK_TIMEOUT 30000
#define BUTTON_CYCLES 4
#define V_CHECK_CYCLES 3
#define VIN_MIN 10.0
#define VIN_MAX 14.0
#define VDC_MIN 4.8
#define VDC_MAX 6.0
#define VBT_MIN 3.0
#define VBT_MAX 4.25
#define VBA_MIN 6.0
#define VBA_MAX 8.4
#define VCC_MIN 4.5
#define VCC_MAX 5.3
// VAR
// резисторы делителя напряжения
const float r1_1 = 200000; // 200K
const float r1_2 = 100000; // 100K
const float r2_1 = 100000; // 100K
const float r2_2 = 100000; // 100K
const float r3_1 = 100000; // 100K
const float r3_2 = 100000; // 100K
const float r4_1 = 200000; // 200K
const float r4_2 = 100000; // 100K
// эту константу (typVbg) необходимо откалибровать индивидуально
const float typVbg = 1.083; // 1.0 -- 1.2
float vcc = 0.0;
float Vmax1, Vmax2, Vmax3, Vmax4;
float kin, kdc, kbt, kba;
float vin, vdc, vbt, vba;
float tin, tdc, tbt, tba;
//char *stime;
byte cmd = 0x00;
byte ext = 0x00;
byte sum = 0x00;
unsigned long lastCommandTime = 0;
byte autoResponse = 0x00;
byte byteResponse = 0x00;
boolean needByte = false;
boolean needSumm = false;
float floatResponse = 0.0;
boolean needFloat = false;
byte floatByte = 0;
byte ba_count = 0;
unsigned long ba_time;
boolean ba_blocked = false;
byte button_count = 0;
boolean vin_ok = false;
byte vin_count = 0;
boolean vdc_ok = false;
byte vdc_count = 0;
boolean vbt_ok = false;
byte vbt_count = 0;
boolean vba_ok = false;
byte vba_count = 0;
boolean vcc_ok = false;
byte vcc_count = 0;
boolean ba_enabled = true;
boolean lr_enabled = true;
boolean pf_enabled = false;
boolean bl_enabled = false;
boolean bl_powered = false;
boolean bl_error = false;
boolean ba_full = false;
boolean ba_charge = false;
byte status_1 = 0x00;
byte status_2 = 0x00;
// Loop delay
int delay_time = DELAY_TIME;
/****************************************************************************
* Главная программа
****************************************************************************/
void setup() {
if (DEBUG) {
Serial.begin(9600);
Serial.println("---");
delay(1000);
}
// определение опорного напряжения
analogReference(DEFAULT); // DEFAULT INTERNAL использовать vcc как AREF
delay(100);
kin = r1_2 / (r1_1 + r1_2);
kdc = r2_2 / (r2_1 + r2_2);
kbt = r3_2 / (r3_1 + r3_2);
kba = r4_2 / (r4_1 + r4_2);
vcc = readvcc();
Vmax1 = vcc / kin;
Vmax2 = vcc / kdc;
Vmax3 = vcc / kbt;
Vmax4 = vcc / kba;
if (DEBUG) {
Serial.print("Vcc= ");
Serial.println(vcc);
Serial.print("Vmax1= ");
Serial.println(Vmax1);
Serial.print("Vmax2= ");
Serial.println(Vmax2);
Serial.print("Vmax3= ");
Serial.println(Vmax3);
Serial.print("Vmax4= ");
Serial.println(Vmax4);
Serial.println("---");
}
// Initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(answer);
pinMode(R_BL, OUTPUT);
pinMode(R_PF, OUTPUT);
pinMode(R_HX, OUTPUT);
pinMode(R_IS, OUTPUT);
pinMode(BTN_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(BL_RED_PIN, INPUT);
pinMode(BL_GRN_PIN, INPUT);
ba_time = millis();
}
void loop() {
// Timeout protection
if ((lastCommandTime + TIMEOUT < millis())) {
floatResponse = 0.0;
floatByte = 0;
needFloat = false;
autoResponse = TMO_RSP;
}
//vcc = readvcc();
// stime = TimeToString(millis()/1000);
// считываем точное напряжение с A0, где будет находиться наш вольтметр с делителем напряжения
tin = 0.0;
tdc = 0.0;
tbt = 0.0;
tba = 0.0;
for (byte i = 0; i < REP_COUNT; i++) {
tin = tin * readvcc() + analogRead(VIN_PIN);
tdc = tdc * readvcc() + analogRead(VDC_PIN);
tbt = tbt * readvcc() + analogRead(VBT_PIN);
tba = tba * readvcc() + analogRead(VBA_PIN);
delay(10);
}
// tin = (tin * vcc) / 1024.0 / kin / REP_COUNT;
// tdc = (tdc * vcc) / 1024.0 / kdc / REP_COUNT;
// tbt = (tbt * vcc) / 1024.0 / kbt / REP_COUNT;
// tba = (tba * vcc) / 1024.0 / kba / REP_COUNT;
tin = tin / 1024.0 / kin / REP_COUNT;
tdc = tdc / 1024.0 / kdc / REP_COUNT;
tbt = tbt / 1024.0 / kbt / REP_COUNT;
tba = tba / 1024.0 / kba / REP_COUNT;
vin = tin;
vdc = tdc;
vbt = tbt;
if (ba_enabled) vba = tba;
// if (DEBUG && count >= 5) {
// Serial.print("Vcc= ");
// Serial.println(vcc);
// Serial.print("Vin= ");
// Serial.println(vin);
// Serial.print("Vdc= ");
// Serial.println(vdc);
// Serial.print("Vbt= ");
// Serial.println(vbt);
// Serial.print("Vpf= ");
// Serial.println(vpf);
// Serial.println("---");
// count = 0;
// }
// else count++;
// Vin check
if (vin >= VIN_MIN && vin <= VIN_MAX) {
if (! vin_ok) vin_count++;
}
else {
vin_count = 0;
vin_ok = false;
}
if (vin_count >= V_CHECK_CYCLES) vin_ok = true;
// Vdc check
if (vdc >= VDC_MIN && vdc <= VDC_MAX) {
if (! vdc_ok) vdc_count++;
}
else {
vdc_count = 0;
vdc_ok = false;
}
if (vdc_count >= V_CHECK_CYCLES) vdc_ok = true;
// Vbt check
if (vbt >= VBT_MIN && vbt <= VBT_MAX) {
if (! vbt_ok) vbt_count++;
}
else {
vbt_count = 0;
vbt_ok = false;
}
if (vbt_count >= V_CHECK_CYCLES) vbt_ok = true;
// Vba check
if (ba_enabled) {
if (vba >= VBA_MIN && vba <= VBA_MAX) {
if (! vba_ok) vba_count++;
}
else {
vba_count = 0;
vba_ok = false;
}
if (vba_count >= V_CHECK_CYCLES) vba_ok = true;
}
else {
//vba = 0.0;
vba_ok = false;
}
// Vcc check
if (vcc >= VCC_MIN && vcc <= VCC_MAX) {
if (! vcc_ok) vcc_count++;
}
else {
vcc_count = 0;
vcc_ok = false;
}
if (vcc_count >= V_CHECK_CYCLES) vcc_ok = true;
// Auto switch to BA
if (! vin_ok) {
switchToBA();
}
// BL status
bl_powered = false;
bl_error = false;
ba_full = false;
ba_charge = false;
if (vin_ok && bl_enabled) {
delay_time = 0;
// if (DEBUG) {
// unsigned long tmp1, tmp2;
//
// tmp1 = millis();
// while(digitalRead(BL_GRN_PIN) == LOW) {
//
// }
// tmp2 = millis();
//
// Serial.print("time1: ");
// Serial.println(tmp2 - tmp1);
//
// tmp1 = millis();
// while(digitalRead(BL_GRN_PIN) == HIGH) {
//
// }
// tmp2 = millis();
// Serial.print("time2: ");
// Serial.println(tmp2 - tmp1);
//
// }
switch (detectBlink(BL_GRN_PIN)) {
case 0:
ba_full = false;
ba_charge = false;
break;
case 1:
ba_full = true;
ba_charge = false;
bl_powered = true;
break;
case 2:
ba_full = false;
ba_charge = true;
bl_powered = true;
break;
}
if (! ba_charge && ! ba_full) {
switch (detectBlink(BL_RED_PIN)) {
case 0:
bl_powered = false;
bl_error = false;
break;
case 1:
bl_powered = true;
bl_error = false;
break;
case 2:
bl_powered = false;
bl_error = true;
break;
}
}
} else delay_time = DELAY_TIME;
// Button reaction
if (digitalRead(BTN_PIN) == HIGH) {
if (button_count >= BUTTON_CYCLES) {
if (ba_enabled && vin_ok) {
switchToIN();
}
else {
switchToBA();
ba_blocked = true;
}
button_count = 0;
}
else button_count++;
}
else button_count = 0;
// Disable BA block
if (ba_blocked && ba_time + BA_BLOCK_TIMEOUT < millis()) {
ba_blocked = false;
}
// Auto switch to IN
if (vin_ok && ba_enabled && ! ba_blocked && ba_time + BA_TIMEOUT < millis()) {
switchToIN();
}
// Auto enable BL
if (! pf_enabled && ! ba_enabled && vin_ok) {
enableBL();
}
status_1 = 0x00;
if (vcc_ok) status_1 |= 0x01;
if (vin_ok) status_1 |= 0x02;
if (vdc_ok) status_1 |= 0x04;
if (vbt_ok) status_1 |= 0x08;
if (vba_ok) status_1 |= 0x10;
if (lr_enabled) status_1 |= 0x20;
if (ba_enabled) status_1 |= 0x40;
if (ba_blocked) status_1 |= 0x80;
status_2 = 0x00;
if (bl_powered) status_2 |= 0x01;
if (bl_error) status_2 |= 0x02;
if (ba_full) status_2 |= 0x04;
if (ba_charge) status_2 |= 0x08;
// if (vpf_low) status_2 |= 0x10;
// if (vpf_high) status_2 |= 0x20;
if (pf_enabled) status_2 |= 0x40;
if (bl_enabled) status_2 |= 0x80;
// Delay
delay(delay_time);
}
/****************************************************************************
* Функции
****************************************************************************/
float readvcc() {
byte i;
float result = 0.0;
float tmp = 0.0;
for (i = 0; i < REP_COUNT; i++) {
// Read 1.1V reference against Avcc
// set the reference to vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
// works on an Arduino 168 or 328
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(3); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
tmp = (high<<8) | low;
tmp = (typVbg * 1023.0) / tmp;
result = result + tmp;
delay(5);
}
result = result / REP_COUNT;
return result;
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
// Get command
ext = Wire.read();
if (ext == EXT_COM && byteCount == 3) {
cmd = 0x00;
sum = 0x00;
if (Wire.available()) sum = Wire.read();
if (Wire.available()) cmd = Wire.read();
if ((cmd ^ XOR_SEQ) != sum) {
autoResponse = CSE_RSP;
return;
}
}
else {
autoResponse = ERR_RSP;
while(Wire.available()) {
ext = Wire.read();
}
return;
}
// Process command
switch (cmd) {
case COM_GET_VIN:
sendFloat(vin);
break;
case COM_GET_VDC:
sendFloat(vdc);
break;
case COM_GET_VBT:
sendFloat(vbt);
break;
case COM_GET_VBA:
sendFloat(vba);
break;
case COM_GET_VCC:
sendFloat(vcc);
break;
case COM_GET_TEMP:
sendFloat(getInternalTemp());
break;
case COM_GET_STAT1:
sendByte(status_1);
break;
case COM_GET_STAT2:
sendByte(status_2);
break;
case COM_POWER_ON_BL:
digitalWrite(R_BL, HIGH);
bl_enabled = true;
commandResponse();
break;
case COM_SHUTDOWN_BL:
digitalWrite(R_BL, LOW);
bl_enabled = false;
commandResponse();
break;
case COM_POWER_ON_PF:
digitalWrite(R_PF, HIGH);
pf_enabled = true;
commandResponse();
break;
case COM_SHUTDOWN_PF:
digitalWrite(R_PF, LOW);
pf_enabled = false;
commandResponse();
break;
case COM_SWITCH_TO_IS:
commandResponse(switchToIS());
break;
case COM_SWITCH_TO_LR:
commandResponse(switchToLR());
break;
case COM_SWITCH_TO_IN:
commandResponse(switchToIN());
break;
case COM_SWITCH_TO_BA:
commandResponse(switchToBA());
break;
case COM_ENABLE_PF:
enablePF();
commandResponse();
break;
case COM_DISABLE_PF:
disablePF();
commandResponse();
break;
case COM_ENABLE_BL:
enableBL();
commandResponse();
break;
case COM_DISABLE_BL:
disableBL();
commandResponse();
break;
default:
autoResponse = ERR_RSP;
break;
}
}
}
void commandResponse() {
lastCommandTime = millis();
autoResponse = OK_RSP;
}
void commandResponse(byte response) {
lastCommandTime = millis();
autoResponse = response;
}
void sendByte(byte value) {
lastCommandTime = millis();
byteResponse = value;
needSumm = false;
needByte = true;
}
void sendFloat(float value) {
lastCommandTime = millis();
floatResponse = value;
floatByte = 0;
needFloat = true;
}
byte cSum(byte value) {
return value ^ XOR_SEQ;
}
byte cSum(byte *data, byte dataSize) {
byte tmp = 0x00;
for (byte i = 0; i < dataSize; i++) {
tmp = tmp ^ data[i];
}
return tmp ^ XOR_SEQ;
}
void answer() {
// Want float value?
if (needFloat) {
// Get access to the float as a byte-array:
byte *data = (byte *) &floatResponse;
if (floatByte < sizeof(floatResponse)) {
// Send byte
Wire.write(data[floatByte]);
floatByte++;
}
else {
// Send control sum
Wire.write(cSum(data, sizeof(floatResponse)));
needFloat = false;
}
}
else {
// Want byte value?
if (needByte) {
if (!needSumm) {
// Send byte
Wire.write(byteResponse);
needSumm = true;
}
else {
// Send control sum
Wire.write(cSum(byteResponse));
needSumm = false;
needByte = false;
}
}
else {
// Want something else?
Wire.write(autoResponse);
}
}
// Nothing more to send
autoResponse = NO_RSP;
}
byte switchToLR() {
if (vbt_ok) {
digitalWrite(R_HX, LOW);
lr_enabled = true;
return OK_RSP;
}
else return BLK_RSP;
}
byte switchToIS() {
digitalWrite(R_HX, HIGH);
lr_enabled = false;
return OK_RSP;
}
byte switchToBA() {
if (! ba_enabled) {
// Disable BL
if (bl_enabled) {
digitalWrite(R_BL, LOW);
bl_enabled = false;
//delay(500);
}
digitalWrite(R_IS, LOW);
ba_enabled = true;
digitalWrite(LED_PIN, LOW);
ba_time = millis();
ba_blocked = true;
}
return OK_RSP;
}
byte switchToIN() {
if (vin_ok && ba_enabled) {
digitalWrite(R_IS, HIGH);
ba_enabled = false;
digitalWrite(LED_PIN, HIGH);
return OK_RSP;
}
else return BLK_RSP;
}
void enablePF() {
if (bl_enabled) {
digitalWrite(R_BL, LOW);
bl_enabled = false;
//delay(500);
}
digitalWrite(R_PF, HIGH);
pf_enabled = true;
}
void disablePF() {
digitalWrite(R_PF, LOW);
pf_enabled = false;
}
byte enableBL() {
if (! ba_enabled && ! pf_enabled) {
digitalWrite(R_BL, HIGH);
bl_enabled = true;
return OK_RSP;
}
else return BLK_RSP;
}
void disableBL() {
digitalWrite(R_BL, LOW);
bl_enabled = false;
}
// Get the internal temperature
float getInternalTemp() {
unsigned int wADC;
float t;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
while (bit_is_set(ADCSRA,ADSC));
wADC = ADCW;
t = (wADC - 324.31 ) / 1.22;
return(t);
}
byte detectBlink(byte pin) {
// Return codes:
// 0 - LOW
// 1 - HIGH
// 2 - BLINK
byte low_count = 0;
byte high_count = 0;
byte i = 0;
byte pin_level;
for (i = 0; i < 3; i++) {
pin_level = digitalRead(pin);
if (pin_level == HIGH) high_count++;
if (pin_level == LOW) low_count++;
delay(300);
}
if (low_count > 0 && high_count == 0)
return 0;
else
if (high_count > 0 && low_count == 0)
return 1;
else
return 2;
}

1051
HXpower2/HXpower2.ino Normal file

File diff suppressed because it is too large Load Diff

899
HXpower3/HXpower3.ino Normal file
View File

@ -0,0 +1,899 @@
/////////////////////////////////////////
// HXbot HXpower firmware /
// EoF 2016 EoF@itphx.ru /
/////////////////////////////////////////
#include <Wire.h>
// DEBUG
#define DEBUG 0
// DEFINE
#define SLAVE_ADDRESS 0x05
#define XOR_SEQ 0xFF
#define EXT_COM 0xAA
#define AIN_PIN A9
#define ADC_PIN A8
#define AUS_PIN A7
#define ABA_PIN A6
#define VIN_PIN A5
#define VDC_PIN A4
#define VBT_PIN A3
#define VBA_PIN A2
#define VZU_PIN A1
#define VPF_PIN A0
#define R_BA 11
#define R_PF 5
#define R_DC 1
#define R_US 7
//#define RED_PIN 10
//#define GRN_PIN 12
#define INC_PIN 0
#define LED_PIN 13
#define REP_COUNT 5
#define TIMEOUT 5000
#define BUTTON_REACTION_TIME 5000
// COMMANDS
// VOLTMETERS
#define COM_GET_VIN 0x01
#define COM_GET_VDC 0x02
#define COM_GET_VBT 0x03
#define COM_GET_VBA 0x04
#define COM_GET_VPF 0x05
#define COM_GET_VZU 0x06
#define COM_GET_VCC 0x07
// AMPERMETERS
#define COM_GET_AUS 0x21
#define COM_GET_ABA 0x22
#define COM_GET_AIN 0x23
#define COM_GET_ADC 0x24
// STATUS
#define COM_GET_STAT1 0x08
#define COM_GET_STAT2 0x09
#define COM_GET_STAT3 0x20
// TEMP
#define COM_GET_TEMP 0x10
// RELAYS
#define COM_ENABLE_BA 0x11 // 17
#define COM_ENABLE_PF 0x12 // 18
#define COM_ENABLE_EX 0x13 // 19
#define COM_ENABLE_US 0x14 // 20
#define COM_DISABLE_BA 0x15 // 21
#define COM_DISABLE_PF 0x16 // 22
#define COM_DISABLE_EX 0x17 // 23
#define COM_DISABLE_US 0x18 // 24
#define COM_RUN 0x1B // 27
#define COM_STOP 0x1C // 28
#define COM_RESET_US 0x1D // 29
#define OK_RSP 0x00
#define NO_RSP 0xFF
#define ERR_RSP 0x01
#define BLK_RSP 0x02
#define CSE_RSP 0x03
#define IOE_RSP 0x04
#define TMO_RSP 0x05
// CONST
#define EX_BLOCK_TIMEOUT 30000
#define BA_BLOCK_TIMEOUT 30000
#define BA_FULL_CHECK_CYCLES 20
#define V_CHECK_CYCLES 10
//#define MAX_VBT_FAIL 15
#define AREF 5
#define VIN_MIN 14.0
#define VIN_MAX 20.0
#define VDC_MIN 5.0
#define VDC_MAX 6.5
#define VBT_MIN 6.6
#define VBT_MAX 8.6
#define VBA_MIN 9.0
#define VBA_MAX 13.0
#define VBA_FULL 12.0
#define VPF_MIN 7.2
#define VPF_MAX 10.0
#define VZU_MIN 5.0
#define VZU_MAX 6.3
#define VCC_MIN 4.3
#define VCC_MAX 5.3
#define AUS_MIN 0.1
#define AUS_MAX 5.0
#define ABA_MIN 0.1
#define ABA_MAX 5.0
#define AIN_MIN 0.1
#define AIN_MAX 5.0
#define ADC_MIN 0.1
#define ADC_MAX 5.0
// VAR
// резисторы делителя напряжения
const float r1_1 = 20000; // 20K
const float r1_2 = 10000; // 10K
const float r2_1 = 10380; // 10K
const float r2_2 = 10000; // 10K
const float r3_1 = 10000; // 10K
const float r3_2 = 10000; // 10K
const float r4_1 = 20330; // 20K
const float r4_2 = 10000; // 10K
const float r5_1 = 1060; // 1K
const float r5_2 = 1000; // 1K
const float r6_1 = 1000; // 1K
const float r6_2 = 1000; // 1K
// эту константу (typVbg) необходимо откалибровать индивидуально
const float typVbg = 1.08; // 1.0 -- 1.2
float vcc = 0.0, tcc;
float kin, kdc, kbt, kba, kpf, kzu;
float vin, vdc, vbt, vba, vpf, vzu;
float tin, tdc, tbt, tba, tpf, tzu;
float aus, aba, ain, adc;
float uus, uba, uin, udc;
byte cmd = 0x00;
byte ext = 0x00;
byte sum = 0x00;
unsigned long lastCommandTime = 0;
byte autoResponse = 0x00;
byte byteResponse = 0x00;
boolean needByte = false;
boolean needSumm = false;
float floatResponse = 0.0;
boolean needFloat = false;
byte floatByte = 0;
unsigned long ex_time, ba_time;
boolean ex_blocked = false, ba_blocked = false;
byte ba_full_count = 0;
//boolean ex_requested = false;
unsigned long inc_time;
boolean vin_ok = false;
byte vin_count = 0;
boolean vdc_ok = false;
byte vdc_count = 0;
boolean vbt_ok = false, vbt_fail = false;
byte vbt_count = 0, vbt_fail_count = 0;
boolean vba_ok = false;
byte vba_count = 0;
boolean vpf_ok = false;
byte vpf_count = 0;
boolean vzu_ok = false;
byte vzu_count = 0;
boolean vcc_ok = false;
byte vcc_count = 0;
boolean aus_ok = false;
byte aus_count = 0;
boolean aba_ok = false;
byte aba_count = 0;
boolean ain_ok = false;
byte ain_count = 0;
boolean adc_ok = false;
byte adc_count = 0;
boolean ba_enabled = false;
boolean ex_enabled = false;
boolean pf_enabled = false;
boolean us_enabled = true;
boolean ba_full = false;
boolean ba_charge = false;
byte status_1 = 0x00;
byte status_2 = 0x00;
byte status_3 = 0x00;
/****************************************************************************
* Главная программа
****************************************************************************/
void setup() {
if (DEBUG) {
Serial.begin(9600);
Serial.println("---");
delay(1000);
}
// определение опорного напряжения
analogReference(DEFAULT); // DEFAULT INTERNAL использовать vcc как AREF
kin = r1_2 / (r1_1 + r1_2);
kdc = r2_2 / (r2_1 + r2_2);
kbt = r3_2 / (r3_1 + r3_2);
kba = r4_2 / (r4_1 + r4_2);
kpf = r5_2 / (r5_1 + r5_2);
kzu = r6_2 / (r6_1 + r6_2);
if (DEBUG) {
Serial.print("Vcc= ");
Serial.println(vcc);
Serial.println("---");
}
// Initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(answer);
pinMode(R_BA, OUTPUT);
pinMode(R_PF, OUTPUT);
pinMode(R_DC, OUTPUT);
pinMode(R_US, OUTPUT);
pinMode(VIN_PIN, INPUT);
pinMode(VDC_PIN, INPUT);
pinMode(VBT_PIN, INPUT);
pinMode(VBA_PIN, INPUT);
pinMode(VPF_PIN, INPUT);
pinMode(VZU_PIN, INPUT);
pinMode(AUS_PIN, INPUT);
pinMode(ABA_PIN, INPUT);
pinMode(AIN_PIN, INPUT);
pinMode(ADC_PIN, INPUT);
pinMode(INC_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
ex_time = millis();
}
void loop() {
// Timeout protection
if ((lastCommandTime + TIMEOUT < millis())) {
floatResponse = 0.0;
floatByte = 0;
needFloat = false;
autoResponse = TMO_RSP;
}
// BLOCK OF MAGIC
readvcc();
analogRead(VIN_PIN);
readvcc();
analogRead(VIN_PIN);
readvcc();
analogRead(VIN_PIN);
// MAGIC
// Get voltages
tin = 0.0;
tdc = 0.0;
tbt = 0.0;
tba = 0.0;
tpf = 0.0;
tzu = 0.0;
tin += readvcc() * analogRead(VIN_PIN);
tdc += readvcc() * analogRead(VDC_PIN);
tbt += readvcc() * analogRead(VBT_PIN);
tba += readvcc() * analogRead(VBA_PIN);
tpf += readvcc() * analogRead(VPF_PIN);
tzu += readvcc() * analogRead(VZU_PIN);
tcc = readvcc();
tin = tin / 1024.0 / kin;// / REP_COUNT;
tdc = tdc / 1024.0 / kdc;// / REP_COUNT;
tbt = tbt / 1024.0 / kbt;// / REP_COUNT;
tba = tba / 1024.0 / kba;// / REP_COUNT;
tpf = tpf / 1024.0 / kpf;// / REP_COUNT;
tzu = tzu / 1024.0 / kzu;// / REP_COUNT;
if (tcc > VCC_MIN) vcc = tcc;
vin = tin;
vdc = tdc;
vbt = tbt;
vba = tba;
vpf = tpf;
vzu = tzu;
// Get currents
aus = (analogRead(AUS_PIN) - 512) * 0.0264;
//if (aus < 0) aus *= -1;
aba = (analogRead(ABA_PIN) - 512) * 0.0264;
//if (aba < 0) aba *= -1;
ain = (analogRead(AIN_PIN) - 512) * 0.0264;
//if (ain < 0) ain *= -1;
adc = (analogRead(ADC_PIN) - 512) * 0.0264;
//if (adc < 0) adc *= -1;
if (DEBUG) {
Serial.print("Vcc: ");
Serial.println(vcc);
Serial.print("Vin: ");
Serial.println(vin);
Serial.print("Vdc: ");
Serial.println(vdc);
Serial.print("Vbt: ");
Serial.println(vbt);
Serial.print("Vba: ");
Serial.println(vba);
Serial.print("Vpf: ");
Serial.println(vpf);
Serial.print("Vzu: ");
Serial.println(vzu);
Serial.println("---");
}
// Vin check
if (vin >= VIN_MIN && vin <= VIN_MAX) {
if (! vin_ok) vin_count++;
}
else {
vin_count = 0;
vin_ok = false;
}
if (vin_count >= V_CHECK_CYCLES) vin_ok = true;
// Vdc check
if (vdc >= VDC_MIN && vdc <= VDC_MAX) {
if (! vdc_ok) vdc_count++;
}
else {
vdc_count = 0;
vdc_ok = false;
}
if (vdc_count >= V_CHECK_CYCLES) vdc_ok = true;
// Vbt check
if (vbt >= VBT_MIN && vbt <= VBT_MAX) {
if (! vbt_ok) vbt_count++;
}
else {
vbt_count = 0;
vbt_ok = false;
}
if (vbt_count >= V_CHECK_CYCLES) vbt_ok = true;
// Vba check
if (vba >= VBA_MIN && vba <= VBA_MAX) {
if (! vba_ok) vba_count++;
}
else {
vba_count = 0;
vba_ok = false;
}
if (vba_count >= V_CHECK_CYCLES) vba_ok = true;
// Vpf check
if (vpf >= VPF_MIN && vpf <= VPF_MAX) {
if (! vpf_ok) vpf_count++;
}
else {
vpf_count = 0;
vpf_ok = false;
}
if (vpf_count >= V_CHECK_CYCLES) vpf_ok = true;
// Vzu check
if (vzu >= VZU_MIN && vzu <= VZU_MAX) {
if (! vzu_ok) vzu_count++;
}
else {
vzu_count = 0;
vzu_ok = false;
}
if (vzu_count >= V_CHECK_CYCLES) vzu_ok = true;
// Vcc check
if (vcc >= VCC_MIN && vcc <= VCC_MAX) {
if (! vcc_ok) vcc_count++;
}
else {
vcc_count = 0;
vcc_ok = false;
}
if (vcc_count >= V_CHECK_CYCLES) vcc_ok = true;
// Aus check
if (aus >= AUS_MIN && aus <= AUS_MAX) {
if (! aus_ok) aus_count++;
}
else {
aus_count = 0;
aus_ok = false;
}
if (aus_count >= V_CHECK_CYCLES) aus_ok = true;
// Aba check
if (aba >= ABA_MIN && aba <= ABA_MAX) {
if (! aba_ok) aba_count++;
}
else {
aba_count = 0;
aba_ok = false;
}
if (aba_count >= V_CHECK_CYCLES) aba_ok = true;
// Ain check
if (ain >= AIN_MIN && ain <= AIN_MAX) {
if (! ain_ok) ain_count++;
}
else {
ain_count = 0;
ain_ok = false;
}
if (ain_count >= V_CHECK_CYCLES) ain_ok = true;
// Adc check
if (adc >= ADC_MIN && adc <= ADC_MAX) {
if (! adc_ok) adc_count++;
}
else {
adc_count = 0;
adc_ok = false;
}
if (adc_count >= V_CHECK_CYCLES) adc_ok = true;
// BA full?
if (vba >= VBA_FULL) {
if (! ba_full && ! ba_enabled) ba_full_count++;
}
else {
ba_full_count = 0;
//ba_full = false;
}
if (ba_full_count >= BA_FULL_CHECK_CYCLES) {
ba_full = true;
}
if (ba_enabled && ! in_plugged()) {
ba_full = false;
}
// Auto disable EX
if (! vdc_ok) { // || ((! vin_ok || ! in_plugged()) && ! ex_requested)) {
disableEX();
}
// Disable EX block
if (ex_blocked && ex_time + EX_BLOCK_TIMEOUT < millis()) {
ex_blocked = false;
}
// Auto enable EX
if (vdc_ok && ! ex_blocked) {
enableEX();
}
// Auto enable BA (for charge)
if (! ba_enabled && vin_ok && in_plugged() && ! ba_full && ! ba_blocked) {
enableBA();
}
// Auto disable BA (if charge complete)
if (ba_enabled && ba_full && in_plugged()) { //(ba_full || ! in_plugged())) {
disableBA();
}
// Auto enable BA (for support)
if (! ba_enabled && ! ba_blocked && (! vin_ok || ! in_plugged())) {
enableBA();
}
// Auto disable BA (if discharged)
if (ba_enabled && ! in_plugged() && ! vba_ok) {
disableBA();
}
// Disable BA block
if (ba_blocked && ba_time + BA_BLOCK_TIMEOUT < millis()) {
ba_blocked = false;
}
// Compile status
status_1 = 0x00;
if (vcc_ok) status_1 |= 0x01;
if (vin_ok) status_1 |= 0x02;
if (vdc_ok) status_1 |= 0x04;
if (vbt_ok) status_1 |= 0x08;
if (vba_ok) status_1 |= 0x10;
if (ex_enabled) status_1 |= 0x20;
if (ba_enabled) status_1 |= 0x40;
if (ex_blocked) status_1 |= 0x80;
status_2 = 0x00;
if (in_plugged()) status_2 |= 0x01;
if (ba_blocked) status_2 |= 0x02;
if (ba_full) status_2 |= 0x04;
if (ba_charge) status_2 |= 0x08;
if (vpf_ok) status_2 |= 0x10;
if (vzu_ok) status_2 |= 0x20;
if (pf_enabled) status_2 |= 0x40;
if (us_enabled) status_2 |= 0x80;
status_3 = 0x00;
if (aus_ok) status_3 |= 0x01;
if (aba_ok) status_3 |= 0x02;
if (ain_ok) status_3 |= 0x04;
if (adc_ok) status_3 |= 0x08;
}
/****************************************************************************
* Функции
****************************************************************************/
float readvcc() {
byte i;
float result = 0.0;
float tmp = 0.0;
//for (i = 0; i < REP_COUNT; i++) {
// Read 1.1V reference against Avcc
// set the reference to vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
// works on an Arduino 168 or 328
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(3); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
tmp = (high<<8) | low;
tmp = (typVbg * 1023.0) / tmp;
//result = result + tmp;
// delay(5);
//}
//result = result / REP_COUNT;
return tmp;//result;
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
// Get command
ext = Wire.read();
if (ext == EXT_COM && byteCount == 3) {
cmd = 0x00;
sum = 0x00;
if (Wire.available()) sum = Wire.read();
if (Wire.available()) cmd = Wire.read();
if ((cmd ^ XOR_SEQ) != sum) {
autoResponse = CSE_RSP;
return;
}
}
else {
autoResponse = ERR_RSP;
while(Wire.available()) {
ext = Wire.read();
}
return;
}
// Process command
switch (cmd) {
case COM_GET_VIN:
sendFloat(vin);
break;
case COM_GET_VDC:
sendFloat(vdc);
break;
case COM_GET_VBT:
sendFloat(vbt);
break;
case COM_GET_VBA:
sendFloat(vba);
break;
case COM_GET_VPF:
sendFloat(vpf);
break;
case COM_GET_VZU:
sendFloat(vzu);
break;
case COM_GET_VCC:
sendFloat(vcc);
break;
case COM_GET_AUS:
sendFloat(aus);
break;
case COM_GET_ABA:
sendFloat(aba);
break;
case COM_GET_AIN:
sendFloat(ain);
break;
case COM_GET_ADC:
sendFloat(adc);
break;
case COM_GET_TEMP:
sendFloat(getInternalTemp());
break;
case COM_GET_STAT1:
sendByte(status_1);
break;
case COM_GET_STAT2:
sendByte(status_2);
break;
case COM_GET_STAT3:
sendByte(status_3);
break;
case COM_ENABLE_BA:
commandResponse(enableBA());
break;
case COM_DISABLE_BA:
commandResponse(disableBA());
break;
case COM_ENABLE_EX:
commandResponse(enableEX());
break;
case COM_DISABLE_EX:
commandResponse(disableEX());
break;
case COM_ENABLE_PF:
enablePF();
commandResponse();
break;
case COM_DISABLE_PF:
disablePF();
commandResponse();
break;
case COM_ENABLE_US:
enableUS();
commandResponse();
break;
case COM_DISABLE_US:
disableUS();
commandResponse();
break;
case COM_RESET_US:
resetUS();
commandResponse();
break;
default:
autoResponse = ERR_RSP;
break;
}
}
}
void commandResponse() {
lastCommandTime = millis();
autoResponse = OK_RSP;
}
void commandResponse(byte response) {
lastCommandTime = millis();
autoResponse = response;
}
void sendByte(byte value) {
lastCommandTime = millis();
byteResponse = value;
needSumm = false;
needByte = true;
}
void sendFloat(float value) {
lastCommandTime = millis();
floatResponse = value;
floatByte = 0;
needFloat = true;
}
byte cSum(byte value) {
return value ^ XOR_SEQ;
}
byte cSum(byte *data, byte dataSize) {
byte tmp = 0x00;
for (byte i = 0; i < dataSize; i++) {
tmp = tmp ^ data[i];
}
return tmp ^ XOR_SEQ;
}
void answer() {
// Want float value?
if (needFloat) {
// Get access to the float as a byte-array:
byte *data = (byte *) &floatResponse;
if (floatByte < sizeof(floatResponse)) {
// Send byte
Wire.write(data[floatByte]);
floatByte++;
}
else {
// Send control sum
Wire.write(cSum(data, sizeof(floatResponse)));
needFloat = false;
}
}
else {
// Want byte value?
if (needByte) {
if (!needSumm) {
// Send byte
Wire.write(byteResponse);
needSumm = true;
}
else {
// Send control sum
Wire.write(cSum(byteResponse));
needSumm = false;
needByte = false;
}
}
else {
// Want something else?
Wire.write(autoResponse);
}
}
// Nothing more to send
autoResponse = NO_RSP;
}
byte enableEX() {
if (vdc_ok) {
digitalWrite(R_DC, HIGH);
digitalWrite(LED_PIN, HIGH);
ex_enabled = true;
ex_blocked = false;
return OK_RSP;
}
else return BLK_RSP;
}
byte disableEX() {
if (vbt_ok) {
digitalWrite(R_DC, LOW);
digitalWrite(LED_PIN, LOW);
ex_enabled = false;
ex_time = millis();
ex_blocked = true;
return OK_RSP;
}
else return BLK_RSP;
}
void enablePF() {
digitalWrite(R_PF, HIGH);
pf_enabled = true;
}
void disablePF() {
digitalWrite(R_PF, LOW);
pf_enabled = false;
}
byte enableBA() {
if (! (in_plugged() && ! vin_ok)) {
digitalWrite(R_BA, HIGH);
ba_enabled = true;
ba_blocked = false;
return OK_RSP;
}
else return BLK_RSP;
}
byte disableBA() {
if (! (ex_enabled && ! in_plugged() && ! vbt_ok)) {
digitalWrite(R_BA, LOW);
ba_enabled = false;
ba_time = millis();
ba_blocked = true;
return OK_RSP;
}
else return BLK_RSP;
}
void enableUS() {
digitalWrite(R_US, LOW);
us_enabled = true;
}
void disableUS() {
digitalWrite(R_US, HIGH);
us_enabled = false;
}
void resetUS() {
disableUS();
delay(500);
enableUS();
}
// Get the internal temperature
float getInternalTemp() {
unsigned int wADC;
float t;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
while (bit_is_set(ADCSRA,ADSC));
wADC = ADCW;
t = (wADC - 324.31 ) / 1.22;
return(t);
}
bool in_plugged() {
if (digitalRead(INC_PIN) == HIGH) {
return true;
} else {
return false;
}
}

897
HXpower4/HXpower4.ino Normal file
View File

@ -0,0 +1,897 @@
/////////////////////////////////////////
// HXbot HXpower firmware v4a /
// EoF 2016 EoF@itphx.ru /
/////////////////////////////////////////
#include <Wire.h>
// DEBUG
#define DEBUG 0
// DEFINE
#define SLAVE_ADDRESS 0x05
#define XOR_SEQ 0xFF
#define EXT_COM 0xAA
#define AIN_PIN A9
#define ABT_PIN A8
#define ABA_PIN A7
#define AHX_PIN A6
#define VIN_PIN A5
#define VDC_PIN A4
#define VBT_PIN A3
#define VBA_PIN A2
#define VZU_PIN A1
#define VPF_PIN A0
#define R_BT 11
#define R_BA 7
#define R_MV 5
#define R_US 1
//#define RED_PIN 10
//#define GRN_PIN 12
#define INC_PIN 0
#define LED_PIN 13
#define REP_COUNT 5
#define TIMEOUT 5000
#define BUTTON_REACTION_TIME 5000
// COMMANDS
// VOLTMETERS
#define COM_GET_VIN 0x01
#define COM_GET_VDC 0x02
#define COM_GET_VBT 0x03
#define COM_GET_VBA 0x04
#define COM_GET_VPF 0x05
#define COM_GET_VZU 0x06
#define COM_GET_VCC 0x07
// AMPERMETERS
#define COM_GET_ABT 0x21
#define COM_GET_ABA 0x22
#define COM_GET_AIN 0x23
#define COM_GET_AHX 0x24
// STATUS
#define COM_GET_STAT1 0x08
#define COM_GET_STAT2 0x09
#define COM_GET_STAT3 0x20
// TEMP
#define COM_GET_TEMP 0x10
// RELAYS
#define COM_ENABLE_BA 0x11 // 17
#define COM_ENABLE_MV 0x12 // 18
#define COM_ENABLE_BT 0x13 // 19
#define COM_ENABLE_US 0x14 // 20
#define COM_DISABLE_BA 0x15 // 21
#define COM_DISABLE_MV 0x16 // 22
#define COM_DISABLE_BT 0x17 // 23
#define COM_DISABLE_US 0x18 // 24
#define COM_RUN 0x1B // 27
#define COM_STOP 0x1C // 28
#define COM_RESET_US 0x1D // 29
#define OK_RSP 0x00
#define NO_RSP 0xFF
#define ERR_RSP 0x01
#define BLK_RSP 0x02
#define CSE_RSP 0x03
#define IOE_RSP 0x04
#define TMO_RSP 0x05
// CONST
#define BT_BLOCK_TIMEOUT 30000
#define BT_FULL_CHECK_CYCLES 20
#define BA_BLOCK_TIMEOUT 30000
#define BA_FULL_CHECK_CYCLES 20
#define V_CHECK_CYCLES 10
#define AREF 5
#define VIN_MIN 14.0
#define VIN_MAX 25.0
#define VDC_MIN 5.5
#define VDC_MAX 6.5
#define VBT_MIN 6.6
#define VBT_MAX 8.6
#define VBA_MIN 9.0
#define VBA_MAX 13.0
#define VBA_FULL 12.0
#define VPF_MIN 7.2
#define VPF_MAX 10.0
#define VZU_MIN 5.0
#define VZU_MAX 6.3
#define VCC_MIN 4.8
#define VCC_MAX 5.5
#define ABT_MIN 0.1
#define ABT_MAX 5.0
#define ABA_MIN 0.1
#define ABA_MAX 5.0
#define AIN_MIN 0.1
#define AIN_MAX 5.0
#define AHX_MIN 0.1
#define AHX_MAX 5.0
// VAR
// резисторы делителя напряжения
const float r1_1 = 100000; // 100K
const float r1_2 = 10000; // 10K
const float r2_1 = 10380; // 10K
const float r2_2 = 10000; // 10K
const float r3_1 = 20000; // 10K
const float r3_2 = 10000; // 10K
const float r4_1 = 20330; // 20K
const float r4_2 = 10000; // 10K
const float r5_1 = 1060; // 1K
const float r5_2 = 1000; // 1K
const float r6_1 = 1000; // 1K
const float r6_2 = 1000; // 1K
// эту константу (typVbg) необходимо откалибровать индивидуально
const float typVbg = 1.08; // 1.0 -- 1.2
float vcc = 0.0, tcc;
float kin, kdc, kbt, kba, kpf, kzu;
float vin, vdc, vbt, vba, vpf, vzu;
float tin, tdc, tbt, tba, tpf, tzu;
float abt, aba, ain, ahx;
float uus, uba, uin, udc;
byte cmd = 0x00;
byte ext = 0x00;
byte sum = 0x00;
unsigned long lastCommandTime = 0;
byte autoResponse = 0x00;
byte byteResponse = 0x00;
boolean needByte = false;
boolean needSumm = false;
float floatResponse = 0.0;
boolean needFloat = false;
byte floatByte = 0;
unsigned long bt_time, ba_time;
boolean bt_blocked = false, ba_blocked = false;
byte ba_full_count = 0, bt_full_count = 0;
unsigned long inc_time;
boolean vin_ok = false;
byte vin_count = 0;
boolean vdc_ok = false;
byte vdc_count = 0;
boolean vbt_ok = false, vbt_fail = false;
byte vbt_count = 0, vbt_fail_count = 0;
boolean vba_ok = false;
byte vba_count = 0;
boolean vpf_ok = false;
byte vpf_count = 0;
boolean vzu_ok = false;
byte vzu_count = 0;
boolean vcc_ok = false;
byte vcc_count = 0;
boolean abt_ok = false;
byte abt_count = 0;
boolean aba_ok = false;
byte aba_count = 0;
boolean ain_ok = false;
byte ain_count = 0;
boolean ahx_ok = false;
byte ahx_count = 0;
boolean ba_enabled = false;
boolean bt_enabled = true;
boolean mv_enabled = false;
boolean us_enabled = true;
boolean bt_full = false;
boolean bt_charge = false;
boolean ba_full = false;
boolean ba_charge = false;
byte status_1 = 0x00;
byte status_2 = 0x00;
byte status_3 = 0x00;
/****************************************************************************
* Главная программа
****************************************************************************/
void setup() {
if (DEBUG) {
Serial.begin(9600);
Serial.println("---");
delay(1000);
}
// определение опорного напряжения
analogReference(DEFAULT); // DEFAULT INTERNAL использовать vcc как AREF
kin = r1_2 / (r1_1 + r1_2);
kdc = r2_2 / (r2_1 + r2_2);
kbt = r3_2 / (r3_1 + r3_2);
kba = r4_2 / (r4_1 + r4_2);
kpf = r5_2 / (r5_1 + r5_2);
kzu = r6_2 / (r6_1 + r6_2);
if (DEBUG) {
Serial.print("Vcc= ");
Serial.println(vcc);
Serial.println("---");
}
// Initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(answer);
pinMode(R_BT, OUTPUT);
pinMode(R_BA, OUTPUT);
pinMode(R_MV, OUTPUT);
pinMode(R_US, OUTPUT);
pinMode(VIN_PIN, INPUT);
pinMode(VDC_PIN, INPUT);
pinMode(VBT_PIN, INPUT);
pinMode(VBA_PIN, INPUT);
pinMode(VPF_PIN, INPUT);
pinMode(VZU_PIN, INPUT);
pinMode(ABT_PIN, INPUT);
pinMode(ABA_PIN, INPUT);
pinMode(AIN_PIN, INPUT);
pinMode(AHX_PIN, INPUT);
pinMode(INC_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
bt_time = millis();
}
void loop() {
// Timeout protection
if ((lastCommandTime + TIMEOUT < millis())) {
floatResponse = 0.0;
floatByte = 0;
needFloat = false;
autoResponse = TMO_RSP;
}
// BLOCK OF MAGIC
readvcc();
analogRead(VIN_PIN);
readvcc();
analogRead(VIN_PIN);
readvcc();
analogRead(VIN_PIN);
// MAGIC
// Get voltages
tin = 0.0;
tdc = 0.0;
tbt = 0.0;
tba = 0.0;
tpf = 0.0;
tzu = 0.0;
tin += readvcc() * analogRead(VIN_PIN);
tdc += readvcc() * analogRead(VDC_PIN);
tbt += readvcc() * analogRead(VBT_PIN);
tba += readvcc() * analogRead(VBA_PIN);
tpf += readvcc() * analogRead(VPF_PIN);
tzu += readvcc() * analogRead(VZU_PIN);
tcc = readvcc();
tin = tin / 1024.0 / kin;// / REP_COUNT;
tdc = tdc / 1024.0 / kdc;// / REP_COUNT;
tbt = tbt / 1024.0 / kbt;// / REP_COUNT;
tba = tba / 1024.0 / kba;// / REP_COUNT;
tpf = tpf / 1024.0 / kpf;// / REP_COUNT;
tzu = tzu / 1024.0 / kzu;// / REP_COUNT;
if (tcc > VCC_MIN) vcc = tcc;
vin = tin;
vdc = tdc;
vbt = tbt;
vba = tba;
vpf = tpf;
vzu = tzu;
// Get currents
abt = (analogRead(ABT_PIN) - 512) * 0.0264;
//if (abt < 0) abt *= -1;
aba = (analogRead(ABA_PIN) - 512) * 0.0264;
//if (aba < 0) aba *= -1;
ain = (analogRead(AIN_PIN) - 512) * 0.0264;
//if (ain < 0) ain *= -1;
ahx = (analogRead(AHX_PIN) - 512) * 0.0264;
//if (ahx < 0) ahx *= -1;
if (DEBUG) {
Serial.print("Vcc: ");
Serial.println(vcc);
Serial.print("Vin: ");
Serial.println(vin);
Serial.print("Vdc: ");
Serial.println(vdc);
Serial.print("Vbt: ");
Serial.println(vbt);
Serial.print("Vba: ");
Serial.println(vba);
Serial.print("Vpf: ");
Serial.println(vpf);
Serial.print("Vzu: ");
Serial.println(vzu);
Serial.println("---");
}
// Vin check
if (vin >= VIN_MIN && vin <= VIN_MAX) {
if (! vin_ok) vin_count++;
}
else {
vin_count = 0;
vin_ok = false;
}
if (vin_count >= V_CHECK_CYCLES) vin_ok = true;
// Vdc check
if (vdc >= VDC_MIN && vdc <= VDC_MAX) {
if (! vdc_ok) vdc_count++;
}
else {
vdc_count = 0;
vdc_ok = false;
}
if (vdc_count >= V_CHECK_CYCLES) vdc_ok = true;
// Vbt check
if (vbt >= VBT_MIN && vbt <= VBT_MAX) {
if (! vbt_ok) vbt_count++;
}
else {
vbt_count = 0;
vbt_ok = false;
}
if (vbt_count >= V_CHECK_CYCLES) vbt_ok = true;
// Vba check
if (vba >= VBA_MIN && vba <= VBA_MAX) {
if (! vba_ok) vba_count++;
}
else {
vba_count = 0;
vba_ok = false;
}
if (vba_count >= V_CHECK_CYCLES) vba_ok = true;
// Vpf check
if (vpf >= VPF_MIN && vpf <= VPF_MAX) {
if (! vpf_ok) vpf_count++;
}
else {
vpf_count = 0;
vpf_ok = false;
}
if (vpf_count >= V_CHECK_CYCLES) vpf_ok = true;
// Vzu check
if (vzu >= VZU_MIN && vzu <= VZU_MAX) {
if (! vzu_ok) vzu_count++;
}
else {
vzu_count = 0;
vzu_ok = false;
}
if (vzu_count >= V_CHECK_CYCLES) vzu_ok = true;
// Vcc check
if (vcc >= VCC_MIN && vcc <= VCC_MAX) {
if (! vcc_ok) vcc_count++;
}
else {
vcc_count = 0;
vcc_ok = false;
}
if (vcc_count >= V_CHECK_CYCLES) vcc_ok = true;
// Abt check
if (abt >= ABT_MIN && abt <= ABT_MAX) {
if (! abt_ok) abt_count++;
}
else {
abt_count = 0;
abt_ok = false;
}
if (abt_count >= V_CHECK_CYCLES) abt_ok = true;
// Aba check
if (aba >= ABA_MIN && aba <= ABA_MAX) {
if (! aba_ok) aba_count++;
}
else {
aba_count = 0;
aba_ok = false;
}
if (aba_count >= V_CHECK_CYCLES) aba_ok = true;
// Ain check
if (ain >= AIN_MIN && ain <= AIN_MAX) {
if (! ain_ok) ain_count++;
}
else {
ain_count = 0;
ain_ok = false;
}
if (ain_count >= V_CHECK_CYCLES) ain_ok = true;
// Ahx check
if (ahx >= AHX_MIN && ahx <= AHX_MAX) {
if (! ahx_ok) ahx_count++;
}
else {
ahx_count = 0;
ahx_ok = false;
}
if (ahx_count >= V_CHECK_CYCLES) ahx_ok = true;
// // BA full?
// if (vba >= VBA_FULL) {
// if (! ba_full && ! ba_enabled) ba_full_count++;
// }
// else {
// ba_full_count = 0;
// //ba_full = false;
// }
//
// if (ba_full_count >= BA_FULL_CHECK_CYCLES) {
// ba_full = true;
// }
//
// if (ba_enabled && ! in_plugged()) {
// ba_full = false;
// }
// // Auto disable EX
// if (! vdc_ok) { // || ((! vin_ok || ! in_plugged()) && ! ex_requested)) {
// disableEX();
// }
//
// // Disable EX block
// if (ex_blocked && ex_time + EX_BLOCK_TIMEOUT < millis()) {
// ex_blocked = false;
// }
//
// // Auto enable EX
// if (vdc_ok && ! ex_blocked) {
// enableEX();
// }
//
// // Auto enable BA (for charge)
// if (! ba_enabled && vin_ok && in_plugged() && ! ba_full && ! ba_blocked) {
// enableBA();
// }
//
// // Auto disable BA (if charge complete)
// if (ba_enabled && ba_full && in_plugged()) { //(ba_full || ! in_plugged())) {
// disableBA();
// }
//
// // Auto enable BA (for support)
// if (! ba_enabled && ! ba_blocked && (! vin_ok || ! in_plugged())) {
// enableBA();
// }
//
// // Auto disable BA (if discharged)
// if (ba_enabled && ! in_plugged() && ! vba_ok) {
// disableBA();
// }
//
// // Disable BA block
// if (ba_blocked && ba_time + BA_BLOCK_TIMEOUT < millis()) {
// ba_blocked = false;
// }
// Compile status
status_1 = 0x00;
if (vcc_ok) status_1 |= 0x01;
if (vin_ok) status_1 |= 0x02;
if (vdc_ok) status_1 |= 0x04;
if (vbt_ok) status_1 |= 0x08;
if (vba_ok) status_1 |= 0x10;
if (bt_enabled) status_1 |= 0x20;
if (ba_enabled) status_1 |= 0x40;
if (in_plugged()) status_1 |= 0x80;
status_2 = 0x00;
if (bt_blocked) status_2 |= 0x01;
if (ba_blocked) status_2 |= 0x02;
if (bt_full) status_2 |= 0x04;
if (ba_full) status_2 |= 0x08;
if (vpf_ok) status_2 |= 0x10;
if (vzu_ok) status_2 |= 0x20;
if (mv_enabled) status_2 |= 0x40;
if (us_enabled) status_2 |= 0x80;
status_3 = 0x00;
if (abt_ok) status_3 |= 0x01;
if (aba_ok) status_3 |= 0x02;
if (ain_ok) status_3 |= 0x04;
if (ahx_ok) status_3 |= 0x08;
}
/****************************************************************************
* Функции
****************************************************************************/
float readvcc() {
byte i;
float result = 0.0;
float tmp = 0.0;
//for (i = 0; i < REP_COUNT; i++) {
// Read 1.1V reference against Avcc
// set the reference to vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
// works on an Arduino 168 or 328
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(3); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
tmp = (high<<8) | low;
tmp = (typVbg * 1023.0) / tmp;
//result = result + tmp;
// delay(5);
//}
//result = result / REP_COUNT;
return tmp;//result;
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
// Get command
ext = Wire.read();
if (ext == EXT_COM && byteCount == 3) {
cmd = 0x00;
sum = 0x00;
if (Wire.available()) sum = Wire.read();
if (Wire.available()) cmd = Wire.read();
if ((cmd ^ XOR_SEQ) != sum) {
autoResponse = CSE_RSP;
return;
}
}
else {
autoResponse = ERR_RSP;
while(Wire.available()) {
ext = Wire.read();
}
return;
}
// Process command
switch (cmd) {
case COM_GET_VIN:
sendFloat(vin);
break;
case COM_GET_VDC:
sendFloat(vdc);
break;
case COM_GET_VBT:
sendFloat(vbt);
break;
case COM_GET_VBA:
sendFloat(vba);
break;
case COM_GET_VPF:
sendFloat(vpf);
break;
case COM_GET_VZU:
sendFloat(vzu);
break;
case COM_GET_VCC:
sendFloat(vcc);
break;
case COM_GET_ABT:
sendFloat(abt);
break;
case COM_GET_ABA:
sendFloat(aba);
break;
case COM_GET_AIN:
sendFloat(ain);
break;
case COM_GET_AHX:
sendFloat(ahx);
break;
case COM_GET_TEMP:
sendFloat(getInternalTemp());
break;
case COM_GET_STAT1:
sendByte(status_1);
break;
case COM_GET_STAT2:
sendByte(status_2);
break;
case COM_GET_STAT3:
sendByte(status_3);
break;
case COM_ENABLE_BA:
commandResponse(enableBA());
break;
case COM_DISABLE_BA:
commandResponse(disableBA());
break;
case COM_ENABLE_BT:
commandResponse(enableBT());
break;
case COM_DISABLE_BT:
commandResponse(disableBT());
break;
case COM_ENABLE_MV:
enableMV();
commandResponse();
break;
case COM_DISABLE_MV:
disableMV();
commandResponse();
break;
case COM_ENABLE_US:
enableUS();
commandResponse();
break;
case COM_DISABLE_US:
disableUS();
commandResponse();
break;
case COM_RESET_US:
resetUS();
commandResponse();
break;
default:
autoResponse = ERR_RSP;
break;
}
}
}
void commandResponse() {
lastCommandTime = millis();
autoResponse = OK_RSP;
}
void commandResponse(byte response) {
lastCommandTime = millis();
autoResponse = response;
}
void sendByte(byte value) {
lastCommandTime = millis();
byteResponse = value;
needSumm = false;
needByte = true;
}
void sendFloat(float value) {
lastCommandTime = millis();
floatResponse = value;
floatByte = 0;
needFloat = true;
}
byte cSum(byte value) {
return value ^ XOR_SEQ;
}
byte cSum(byte *data, byte dataSize) {
byte tmp = 0x00;
for (byte i = 0; i < dataSize; i++) {
tmp = tmp ^ data[i];
}
return tmp ^ XOR_SEQ;
}
void answer() {
// Want float value?
if (needFloat) {
// Get access to the float as a byte-array:
byte *data = (byte *) &floatResponse;
if (floatByte < sizeof(floatResponse)) {
// Send byte
Wire.write(data[floatByte]);
floatByte++;
}
else {
// Send control sum
Wire.write(cSum(data, sizeof(floatResponse)));
needFloat = false;
}
}
else {
// Want byte value?
if (needByte) {
if (!needSumm) {
// Send byte
Wire.write(byteResponse);
needSumm = true;
}
else {
// Send control sum
Wire.write(cSum(byteResponse));
needSumm = false;
needByte = false;
}
}
else {
// Want something else?
Wire.write(autoResponse);
}
}
// Nothing more to send
autoResponse = NO_RSP;
}
byte enableBT() {
if (vbt_ok) {
digitalWrite(R_BT, LOW);
bt_enabled = true;
bt_blocked = false;
return OK_RSP;
}
else return BLK_RSP;
}
byte disableBT() {
if ((vin_ok && in_plugged()) || (vba_ok && ba_enabled)) {
digitalWrite(R_BT, HIGH);
bt_enabled = false;
bt_time = millis();
bt_blocked = true;
return OK_RSP;
}
else return BLK_RSP;
}
byte enableBA() {
if (vba_ok) {
digitalWrite(R_BA, HIGH);
ba_enabled = true;
ba_blocked = false;
return OK_RSP;
}
else return BLK_RSP;
}
byte disableBA() {
if ((vin_ok && in_plugged()) || (vbt_ok && bt_enabled)) {
digitalWrite(R_BA, LOW);
ba_enabled = false;
ba_time = millis();
ba_blocked = true;
return OK_RSP;
}
else return BLK_RSP;
}
void enableMV() {
digitalWrite(R_MV, HIGH);
mv_enabled = true;
}
void disableMV() {
digitalWrite(R_MV, LOW);
mv_enabled = false;
}
void enableUS() {
digitalWrite(R_US, LOW);
us_enabled = true;
}
void disableUS() {
digitalWrite(R_US, HIGH);
us_enabled = false;
}
void resetUS() {
disableUS();
delay(500);
enableUS();
}
// Get the internal temperature
float getInternalTemp() {
unsigned int wADC;
float t;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
while (bit_is_set(ADCSRA,ADSC));
wADC = ADCW;
t = (wADC - 324.31 ) / 1.22;
return(t);
}
bool in_plugged() {
if (digitalRead(INC_PIN) == HIGH) {
return true;
} else {
return false;
}
}

29
HXtools/RGBconverter.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# MAIN PROGRAM
def main():
color = int(input("Type color 0xHHHHHH>"), 16)
r = color >> 16
g = (color >> 8) & 0x0000FF
b = color & 0x0000FF
r1 = int(r / 255 * 31)
g1 = int(g / 255 * 63)
b1 = int(b / 255 * 31)
color = r1 << 11
color = color + (g1 << 5)
color = color + b1
print('RED: 0x%X, %i' % (r, r1))
print('GREEN: 0x%X, %i' % (g, g1))
print('BLUE: 0x%X, %i' % (b, b1))
print('COLOR: 0x%X' % color)
# MAIN PROGRAM
if __name__ == "__main__":
main()

6
HXtools/hxtools.nja Normal file
View File

@ -0,0 +1,6 @@
{
"venv": "",
"name": "HXtools",
"license": "GNU General Public License v3",
"description": ""
}

1
README.md Normal file
View File

@ -0,0 +1 @@
HXbot

643
REflex/REflex.ino Normal file
View File

@ -0,0 +1,643 @@
/////////////////////////////////////////
// HXbot REflex firmware /
// EoF 2016 EoF@itphx.ru /
/////////////////////////////////////////
#include <PowerFunctions.h>
#include <Ultrasonic.h>
#include <Wire.h>
#include <Servo.h>
// DEBUG
#define DEBUG 1
// DEFINE
#define SLAVE_ADDRESS 0x04
#define XOR_SEQ 0xFF
#define EXT_COM 0xAA
//#define LED_PIN 13
#define IRE_PIN 2
#define IRR_PIN 3
#define SV_PIN 13 // vertical
#define SV_CENTER 150 // 0 - up (min. 60), 180 - down (max. 170)
#define SH_PIN 12 //horisontal
#define SH_CENTER 90 // 0 - right, 180 - left
#define SERVO_DELAY 10 // time interval between servo moves
#define ULTRASONIC_PIN 6
#define DRIVE_CHANNEL 2
#define TIMEOUT 5000
#define HEAD_V_FLAG 0x31
#define HEAD_H_FLAG 0x30
// Front and rear servos
#define SF_PIN 10 // front servo
#define SF_CENTER 96
#define SR_PIN 11 // rear servo
#define SR_CENTER 93
#define FR_STEP 2
// IR distance sensors
#define IRD_FRONT_PIN 0
#define IRD_F_MAX 3.0
#define IRA_FRONT_PIN 1
#define IRA_F_MIN 1.0
#define IRD_REAR_PIN 2
#define IRD_R_MAX 3.0
#define IRA_REAR_PIN 3
#define IRA_R_MIN 1.0
#define IR_REPEAT_COUNT 3
// COMMANDS
// Util
#define COM_PING 0x01
#define COM_GET_TEMP 0x02
#define COM_GET_DISTANCE 0x03
// Stop
#define STOP 0x0F
// Move
#define MOVE_FLAG 0x04
#define MOVE_FLOAT 0x10
#define MOVE_FWD1 0x11
#define MOVE_FWD2 0x12
#define MOVE_FWD3 0x13
#define MOVE_FWD4 0x14
#define MOVE_FWD5 0x15
#define MOVE_FWD6 0x16
#define MOVE_FWD7 0x17
#define MOVE_BREAK 0x18
#define MOVE_REV7 0x19
#define MOVE_REV6 0x1A
#define MOVE_REV5 0x1B
#define MOVE_REV4 0x1C
#define MOVE_REV3 0x1D
#define MOVE_REV2 0x1E
#define MOVE_REV1 0x1F
// Steering
#define STEER_FLAG 0x05
#define STEER_CENTER 0x20
#define STEER_LEFT1 0x21
#define STEER_LEFT2 0x22
#define STEER_LEFT3 0x23
#define STEER_LEFT4 0x24
#define STEER_LEFT5 0x25
#define STEER_LEFT6 0x26
#define STEER_LEFT7 0x27
#define STEER_FIX_CENTER 0x28
#define STEER_RIGHT7 0x29
#define STEER_RIGHT6 0x2A
#define STEER_RIGHT5 0x2B
#define STEER_RIGHT4 0x2C
#define STEER_RIGHT3 0x2D
#define STEER_RIGHT2 0x2E
#define STEER_RIGHT1 0x2F
// Response
#define OK_RSP 0x00
#define NO_RSP 0xFF
#define ERR_RSP 0x01
#define BLK_RSP 0x02
#define CSE_RSP 0x03
#define IOE_RSP 0x04
#define TMO_RSP 0x05
// VAR
const float typVbg = 1.13; // 1.0 -- 1.2
float ird_f, ira_f, ird_r, ira_r;
boolean ird_ignore = false, ira_ignore = false;
byte cmd = 0;
byte flg = 0;
byte ext = 0;
byte autoresponse = 0;
long usDistance = 0;
unsigned long lastCommandTime = 0;
boolean isMove = false;
boolean frBlock = false;
PowerFunctions pfDrive(IRE_PIN, DRIVE_CHANNEL);
Ultrasonic usSensor(ULTRASONIC_PIN);
Servo servV, servH, servF, servR;
byte destV, destH;
unsigned long lastServoMove = 0;
// SETUP
void setup() {
if (DEBUG) {
Serial.println("GO!");
Serial.begin(9600);
}
//pinMode(LED_PIN, OUTPUT);
// Initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(answer);
analogReference(DEFAULT);
destH = SH_CENTER;
destV = SV_CENTER;
if (DEBUG) {
Serial.println("Setup complete");
}
}
// MAIN LOOP
void loop() {
// Timeout protection
if ((lastCommandTime + TIMEOUT < millis()) && isMove) {
pfDrive.combo_pwm(PWM_BRK, PWM_BRK);
servV.detach();
servH.detach();
isMove = false;
autoresponse = TMO_RSP;
}
moveServo();
//usDistance = usSensor.MeasureInCentimeters();
if (DEBUG) {
ird_f = analogRead(IRD_FRONT_PIN) * readvcc() / 1024;
ira_f = analogRead(IRA_FRONT_PIN) * readvcc() / 1024;
ird_r = analogRead(IRD_REAR_PIN) * readvcc() / 1024;
ira_r = analogRead(IRA_REAR_PIN) * readvcc() / 1024;
Serial.print("VCC: ");
Serial.println(readvcc());
Serial.print("IRD_F: ");
Serial.println(ird_f);
Serial.print("IRA_F: ");
Serial.println(ira_f);
Serial.print("IRD_R: ");
Serial.println(ird_r);
Serial.print("IRA_R: ");
Serial.println(ira_r);
Serial.println("------");
delay(1000);
}
//delay(100);
}
void moveResponse(byte rsp = OK_RSP) {
lastCommandTime = millis();
isMove = true;
autoresponse = rsp;
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
// Get command
cmd = Wire.read();
if (cmd == EXT_COM && byteCount == 3) {
flg = 0x00;
ext = 0x00;
if (Wire.available()) ext = Wire.read();
if (Wire.available()) flg = Wire.read();
}
else {
// Cleanup I2C bus
while(Wire.available()) {
ext = Wire.read();
}
}
switch (cmd) {
case COM_PING:
autoresponse = OK_RSP;
break;
case STOP:
pfDrive.combo_pwm(PWM_BRK, PWM_BRK);
moveResponse();
break;
case COM_GET_TEMP:
autoresponse = getInternalTemp();
break;
case COM_GET_DISTANCE:
usDistance = usSensor.MeasureInCentimeters();
if (usDistance >= 255) {
autoresponse = NO_RSP;
} else {
autoresponse = usDistance;
}
break;
case EXT_COM:
switch (flg) {
case HEAD_V_FLAG: case HEAD_H_FLAG:
headControl(flg, ext);
break;
case MOVE_FLAG: case STEER_FLAG:
moveControl(flg, ext);
break;
}
break;
default:
autoresponse = ERR_RSP;
break;
}
}
}
void headControl(byte flg, byte val) {
if (! servV.attached()) servV.attach(SV_PIN);
if (! servH.attached()) servH.attach(SH_PIN);
switch (flg) {
case HEAD_V_FLAG:
destV = val;
break;
case HEAD_H_FLAG:
destH = val;
break;
}
moveResponse();
}
void moveServo() {
byte curV, curH;
if (! isMove) return;
if (lastServoMove + SERVO_DELAY < millis()) {
curV = servV.read();
curH = servH.read();
if (destV < curV) servV.write(curV - 1);
if (destV > curV) servV.write(curV + 1);
if (destH < curH) servH.write(curH - 1);
if (destH > curH) servH.write(curH + 1);
lastServoMove = millis();
}
}
// Callback for sending data
void answer() {
Wire.write(autoresponse);
}
boolean ird_f_ok() {
if (! ird_ignore) {
ird_f = 0.0;
for (byte i = 0; i < IR_REPEAT_COUNT; i++) {
ird_f = ird_f + analogRead(IRD_FRONT_PIN) * readvcc() / 1024;
}
ird_f = ird_f / IR_REPEAT_COUNT;
if (ird_f <= IRD_F_MAX) {
return true;
} else {
return false;
}
} else return true;
}
boolean ird_r_ok() {
if (! ird_ignore) {
ird_r = 0.0;
for (byte i = 0; i < IR_REPEAT_COUNT; i++) {
ird_r = ird_r + analogRead(IRD_REAR_PIN) * readvcc() / 1024;
}
ird_r = ird_r / IR_REPEAT_COUNT;
if (ird_r <= IRD_R_MAX) {
return true;
} else {
return false;
}
} else return true;
}
boolean ira_f_ok() {
if (! ira_ignore) {
ira_f = 0.0;
for (byte i = 0; i < IR_REPEAT_COUNT; i++) {
ira_f = ira_f + analogRead(IRA_FRONT_PIN) * readvcc() / 1024;
}
ira_f = ira_f / IR_REPEAT_COUNT;
if (ira_f >= IRA_F_MIN) {
return true;
} else {
return false;
}
} else return true;
}
boolean ira_r_ok() {
if (! ira_ignore) {
ira_r = 0.0;
for (byte i = 0; i < IR_REPEAT_COUNT; i++) {
ira_r = ira_r + analogRead(IRA_REAR_PIN) * readvcc() / 1024;
}
ira_r = ira_r / IR_REPEAT_COUNT;
if (ira_r >= IRA_R_MIN) {
return true;
} else {
return false;
}
} else return true;
}
void stopMove() {
pfDrive.single_pwm(RED, PWM_BRK);
pfDrive.single_pwm(RED, PWM_BRK);
pfDrive.single_pwm(RED, PWM_BRK);
}
void moveControl(byte flg, byte cmd) {
if (flg == MOVE_FLAG) {
if (cmd >= MOVE_FWD1 && cmd <= MOVE_FWD7) {
if (! ira_f_ok()) {
stopMove();
moveResponse(BLK_RSP);
return;
}
if (! ird_f_ok()) {
stopMove();
moveResponse(BLK_RSP);
return;
}
}
if (cmd >= MOVE_REV7 && cmd <= MOVE_REV1) {
if (! ira_r_ok()) {
stopMove();
moveResponse(BLK_RSP);
return;
}
if (! ird_r_ok()) {
stopMove();
moveResponse(BLK_RSP);
return;
}
}
}
switch (cmd) {
// Moving
case MOVE_FLOAT:
pfDrive.single_pwm(RED, PWM_FLT);
break;
case MOVE_FWD1:
pfDrive.single_pwm(RED, PWM_FWD1);
break;
case MOVE_FWD2:
pfDrive.single_pwm(RED, PWM_FWD2);
break;
case MOVE_FWD3:
pfDrive.single_pwm(RED, PWM_FWD3);
break;
case MOVE_FWD4:
pfDrive.single_pwm(RED, PWM_FWD4);
break;
case MOVE_FWD5:
pfDrive.single_pwm(RED, PWM_FWD5);
break;
case MOVE_FWD6:
pfDrive.single_pwm(RED, PWM_FWD6);
break;
case MOVE_FWD7:
pfDrive.single_pwm(RED, PWM_FWD7);
break;
case MOVE_BREAK:
pfDrive.single_pwm(RED, PWM_BRK);
break;
case MOVE_REV1:
pfDrive.single_pwm(RED, PWM_REV1);
break;
case MOVE_REV2:
pfDrive.single_pwm(RED, PWM_REV2);
break;
case MOVE_REV3:
pfDrive.single_pwm(RED, PWM_REV3);
break;
case MOVE_REV4:
pfDrive.single_pwm(RED, PWM_REV4);
break;
case MOVE_REV5:
pfDrive.single_pwm(RED, PWM_REV5);
break;
case MOVE_REV6:
pfDrive.single_pwm(RED, PWM_REV6);
break;
case MOVE_REV7:
pfDrive.single_pwm(RED, PWM_REV7);
break;
// Steering
case STEER_CENTER:
pfDrive.single_pwm(BLUE, PWM_FLT);
frControl(cmd);
break;
case STEER_LEFT1:
pfDrive.single_pwm(BLUE, PWM_FWD1);
frControl(cmd);
break;
case STEER_LEFT2:
pfDrive.single_pwm(BLUE, PWM_FWD2);
frControl(cmd);
break;
case STEER_LEFT3:
pfDrive.single_pwm(BLUE, PWM_FWD3);
frControl(cmd);
break;
case STEER_LEFT4:
pfDrive.single_pwm(BLUE, PWM_FWD4);
frControl(cmd);
break;
case STEER_LEFT5:
pfDrive.single_pwm(BLUE, PWM_FWD5);
frControl(cmd);
break;
case STEER_LEFT6:
pfDrive.single_pwm(BLUE, PWM_FWD6);
frControl(cmd);
break;
case STEER_LEFT7:
pfDrive.single_pwm(BLUE, PWM_FWD7);
frControl(cmd);
break;
case STEER_FIX_CENTER:
pfDrive.single_pwm(BLUE, PWM_BRK);
frControl(cmd);
break;
case STEER_RIGHT1:
pfDrive.single_pwm(BLUE, PWM_REV1);
frControl(cmd);
break;
case STEER_RIGHT2:
pfDrive.single_pwm(BLUE, PWM_REV2);
frControl(cmd);
break;
case STEER_RIGHT3:
pfDrive.single_pwm(BLUE, PWM_REV3);
frControl(cmd);
break;
case STEER_RIGHT4:
pfDrive.single_pwm(BLUE, PWM_REV4);
frControl(cmd);
break;
case STEER_RIGHT5:
pfDrive.single_pwm(BLUE, PWM_REV5);
frControl(cmd);
break;
case STEER_RIGHT6:
pfDrive.single_pwm(BLUE, PWM_REV6);
frControl(cmd);
break;
case STEER_RIGHT7:
pfDrive.single_pwm(BLUE, PWM_REV7);
frControl(cmd);
break;
default:
moveResponse(NO_RSP);
return;
break;
}
// Send response
moveResponse();
}
void frControl(byte cmd) {
if (! frBlock) {
if (! servF.attached()) servF.attach(SF_PIN);
if (! servR.attached()) servR.attach(SR_PIN);
switch (cmd) {
case STEER_CENTER:
servF.write(SF_CENTER);
servR.write(SR_CENTER);
break;
case STEER_LEFT1:
servF.write(SF_CENTER - FR_STEP * 1);
servR.write(SR_CENTER + FR_STEP * 1);
break;
case STEER_LEFT2:
servF.write(SF_CENTER - FR_STEP * 2);
servR.write(SR_CENTER + FR_STEP * 2);
break;
case STEER_LEFT3:
servF.write(SF_CENTER - FR_STEP * 3);
servR.write(SR_CENTER + FR_STEP * 3);
break;
case STEER_LEFT4:
servF.write(SF_CENTER - FR_STEP * 4);
servR.write(SR_CENTER + FR_STEP * 4);
break;
case STEER_LEFT5:
servF.write(SF_CENTER - FR_STEP * 5);
servR.write(SR_CENTER + FR_STEP * 5);
break;
case STEER_LEFT6:
servF.write(SF_CENTER - FR_STEP * 6);
servR.write(SR_CENTER + FR_STEP * 6);
break;
case STEER_LEFT7:
servF.write(SF_CENTER - FR_STEP * 7);
servR.write(SR_CENTER + FR_STEP * 7);
break;
case STEER_FIX_CENTER:
servF.write(SF_CENTER);
servR.write(SR_CENTER);
break;
case STEER_RIGHT1:
servF.write(SF_CENTER + FR_STEP * 1);
servR.write(SR_CENTER - FR_STEP * 1);
break;
case STEER_RIGHT2:
servF.write(SF_CENTER + FR_STEP * 2);
servR.write(SR_CENTER - FR_STEP * 2);
break;
case STEER_RIGHT3:
servF.write(SF_CENTER + FR_STEP * 3);
servR.write(SR_CENTER - FR_STEP * 3);
break;
case STEER_RIGHT4:
servF.write(SF_CENTER + FR_STEP * 4);
servR.write(SR_CENTER - FR_STEP * 4);
break;
case STEER_RIGHT5:
servF.write(SF_CENTER + FR_STEP * 5);
servR.write(SR_CENTER - FR_STEP * 5);
break;
case STEER_RIGHT6:
servF.write(SF_CENTER + FR_STEP * 6);
servR.write(SR_CENTER - FR_STEP * 6);
break;
case STEER_RIGHT7:
servF.write(SF_CENTER + FR_STEP * 7);
servR.write(SR_CENTER - FR_STEP * 7);
break;
default:
servF.write(SF_CENTER);
servR.write(SR_CENTER);
break;
}
}
}
// Get the internal temperature of the arduino
double getInternalTemp(void) {
unsigned int wADC;
double t;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
while (bit_is_set(ADCSRA,ADSC));
wADC = ADCW;
t = (wADC - 324.31 ) / 1.22;
return (t);
}
float readvcc() {
float tmp = 0.0;
// Read 1.1V reference against Avcc
// set the reference to vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
// works on an Arduino 168 or 328
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(3); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
tmp = (high<<8) | low;
tmp = (typVbg * 1023.0) / tmp;
return tmp;
}

28
reset-hxlcd Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
# You need to have installed Wiring Pi library to be able
# to use this script
# see http://wiringpi.com/download-and-install/
# define GPIO number where RESET line (DTR) is connected to
# here GPIO 18
io=24
# Set IO pin to output
gpio -g mode $io out
# Set IO pin to LOW (bring reset to GND)
echo -n "Resetting with GPIO"$io"..."
gpio -g write $io 0
# wait little time
sleep 1
# Set IO pin to HIGH (release reset to VDD)
gpio -g write $io 1
echo "done"
# Optionnal, you can just after reset launch a
# serial connection to Arduino
# uncomment the following line to do it
#picocom -b 115200 --imap lfcrlf /dev/ttyS0

27
reset-hxpower Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
# You need to have installed Wiring Pi library to be able
# to use this script
# see http://wiringpi.com/download-and-install/
# define GPIO number where RESET line (DTR) is connected to
# here GPIO 18
io=25
# Set IO pin to output
gpio -g mode $io out
# Set IO pin to LOW (bring reset to GND)
echo -n "Resetting with GPIO"$io"..."
gpio -g write $io 0
# wait little time
sleep 1
# Set IO pin to HIGH (release reset to VDD)
gpio -g write $io 1
echo "done"
# Optionnal, you can just after reset launch a
# serial connection to Arduino
# uncomment the following line to do it
#picocom -b 115200 --imap lfcrlf /dev/ttyS0

27
reset-reflex Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
# You need to have installed Wiring Pi library to be able
# to use this script
# see http://wiringpi.com/download-and-install/
# define GPIO number where RESET line (DTR) is connected to
# here GPIO 18
io=18
# Set IO pin to output
gpio -g mode $io out
# Set IO pin to LOW (bring reset to GND)
echo -n "Resetting with GPIO"$io"..."
gpio -g write $io 0
# wait little time
sleep 1
# Set IO pin to HIGH (release reset to VDD)
gpio -g write $io 1
echo "done"
# Optionnal, you can just after reset launch a
# serial connection to Arduino
# uncomment the following line to do it
#picocom -b 115200 --imap lfcrlf /dev/ttyS0