Mercurial > code > home > repos > homeauto
diff service/arduinoNode/write_arduino_code.py @ 229:07ee72a042db
refactor to write_arduino_node
Ignore-this: 7b613fe7aa1cef2c88f190db1fcc1c4a
author | drewp@bigasterisk.com |
---|---|
date | Thu, 28 Jan 2016 00:21:31 -0800 |
parents | |
children | 3010238b94a0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/arduinoNode/write_arduino_code.py Thu Jan 28 00:21:31 2016 -0800 @@ -0,0 +1,118 @@ +import tempfile, subprocess, logging, os +log = logging.getLogger('arduino_code') + +def writeMakefile(dev, tag, allLibs): + return ''' +BOARD_TAG = %(tag)s +USER_LIB_PATH := %(libs)s +ARDUINO_LIBS = %(arduinoLibs)s +MONITOR_PORT = %(dev)s + +include /usr/share/arduino/Arduino.mk + ''' % { + 'dev': dev, + 'tag': tag, + 'libs': os.path.abspath('arduino-libraries'), + 'arduinoLibs': ' '.join(allLibs), + } + +def writeCode(baudrate, devs, devCommandNum): + generated = { + 'baudrate': baudrate, + 'includes': '', + 'global': '', + 'setups': '', + 'polls': '', + 'idles': '', + 'actions': '', + } + for attr in ['includes', 'global', 'setups', 'polls', 'idles', + 'actions']: + for dev in devs: + if attr == 'includes': + gen = '\n'.join('#include "%s"\n' % inc + for inc in dev.generateIncludes()) + elif attr == 'global': gen = dev.generateGlobalCode() + elif attr == 'setups': gen = dev.generateSetupCode() + elif attr == 'polls': gen = dev.generatePollCode() + elif attr == 'idles': gen = dev.generateIdleCode() + elif attr == 'actions': + code = dev.generateActionCode() + if code: + gen = '''else if (cmd == %(cmdNum)s) { + %(code)s + Serial.write('k'); + } + ''' % dict(cmdNum=devCommandNum[dev.uri], + code=code) + else: + gen = '' + else: + raise NotImplementedError + + if gen: + generated[attr] += '// for %s\n%s\n' % (dev.uri, gen.strip()) + + code = ''' +%(includes)s + +%(global)s +byte frame=1; +unsigned long lastFrame=0; + +void setup() { + Serial.begin(%(baudrate)d); + Serial.flush(); + %(setups)s +} + +void idle() { + // this slowdown is to spend somewhat less time PWMing, to reduce + // leaking from on channels to off ones (my shift register has no + // latching) + if (micros() < lastFrame + 80) { + return; + } + lastFrame = micros(); + frame++; + %(idles)s +} + +void loop() { + byte head, cmd; + idle(); + if (Serial.available() >= 2) { + head = Serial.read(); + if (head != 0x60) { + Serial.flush(); + return; + } + cmd = Serial.read(); + if (cmd == 0x00) { // poll + %(polls)s + Serial.write('x'); + } else if (cmd == 0x01) { // get code checksum + Serial.write("CODE_CHECKSUM"); + } + %(actions)s + } +} + ''' % generated + return code + +def indent(code): + try: + with tempfile.SpooledTemporaryFile() as codeFile: + codeFile.write(code) + codeFile.seek(0) + code = subprocess.check_output([ + 'indent', + '-linux', + '-fc1', # ok to indent comments + '-i4', # 4-space indent + '-sob' # swallow blanks (not working) + ], stdin=codeFile) + except OSError as e: + log.warn("indent failed (%r)", e) + return code +