Unverified Commit cc7a7a0c authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Add app for UART→DMX on Arduino Nano (ATMeg328P)

parent cac790cd
Loading
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
#
# Automatically generated file; DO NOT EDIT.
# Configuration
#

#
# System
#
# CONFIG_loop is not set
# CONFIG_wakeup is not set
# CONFIG_aspectc is not set
CONFIG_timer_freq=10
# CONFIG_framebuffer is not set

#
# Libraries
#
# CONFIG_lib_inflate is not set
CONFIG_arch_arduino_nano=y
# CONFIG_arch_arduino_uno is not set
# CONFIG_arch_atmega2560 is not set
# CONFIG_arch_blinkenrocket is not set
# CONFIG_arch_infineon_tc299_mock is not set
# CONFIG_arch_infineon_tc397_mock is not set
# CONFIG_arch_lm4f120h5qr_stellaris is not set
# CONFIG_arch_lora32u4ii is not set
# CONFIG_arch_msp430fr5969lp is not set
# CONFIG_arch_msp430fr5994lp is not set
# CONFIG_arch_posix is not set
# CONFIG_arch_rm46l8lp is not set
# CONFIG_arch_stm32f103c8t6 is not set
# CONFIG_arch_stm32f446re_nucleo is not set
# CONFIG_arch_stm32f746zg_nucleo is not set
# CONFIG_arch_stm32h747i_disco is not set
# CONFIG_arch_tc1796_triboard is not set
CONFIG_arch="arduino-nano"

#
# Arduino Nano Configuration
#
CONFIG_arch_arduino_nano_cpufreq=16000000
# CONFIG_arch_arduino_nano_driver_adc is not set
# CONFIG_arch_arduino_nano_driver_i2c is not set
# CONFIG_arch_arduino_nano_driver_neopixel is not set
# CONFIG_arch_arduino_nano_driver_spi is not set
CONFIG_arch_arduino_nano_driver_stdin=y
CONFIG_arch_arduino_nano_driver_timer=y
CONFIG_arch_arduino_nano_driver_dmx=y
CONFIG_arch_arduino_nano_mega328=y
# CONFIG_arch_arduino_nano_mega168 is not set
# CONFIG_arch_arduino_nano_driver_uptime is not set
# CONFIG_arch_arduino_nano_driver_counter is not set
# CONFIG_app_donothing is not set
# CONFIG_app_etcontroller is not set
# CONFIG_app_mqtt_to_dmx_atmega2560 is not set
# CONFIG_app_treebench is not set
# CONFIG_app_treebench_copy is not set
CONFIG_app_uart_to_dmx_mega328=y
CONFIG_app="uart-to-dmx-mega328"
CONFIG_meta_driver_dmx=y
CONFIG_meta_driver_stdin=y
CONFIG_meta_driver_timer=y

#
# Drivers
#
# CONFIG_driver_softi2c is not set
+6 −0
Original line number Diff line number Diff line
# Copyright 2020 Birte Kristina Friesel
#
# SPDX-License-Identifier: CC0-1.0

prompt "UART to DMX gateway on Arduino Nano, with TDMA between UART in and DMX out"
depends on !loop && !wakeup && meta_driver_dmx && meta_driver_stdin && meta_driver_timer
+7 −0
Original line number Diff line number Diff line
# UART → DMX Gateway for Arduino Nano boards

Setup:

* Connect UART TX to MAX485 TX → DMX output
* Copy .../uart-to-dmx-mega328/.config to multipass/.config
* Run `./mp`
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 Birte Kristina Friesel
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include "arch.h"
#include "driver/gpio.h"
#include "driver/stdout.h"
#include "driver/stdin.h"
#include "driver/dmx.h"
#include "driver/timer.h"

#include <string.h>

volatile unsigned char timer_running = 16;
char buffer[64];
unsigned char buf_pos = 0;
unsigned char do_wdr = 0;

bool input_to_dmx(void)
{
	unsigned char num = 0;
	unsigned char dmx_frame = 1;
	unsigned int offset = 0;

#if DEBUG
	kout << "parsing: " << buffer << endl;
#endif

	if (!strncmp(buffer, "TX:", 3)) {
		offset = 3;
	} else {
		return false;
	}

	for (unsigned int i = offset; (i < buf_pos) && buffer[i] ; i++) {
		if ((buffer[i] >= '0') && (buffer[i] <= '9')) {
			num *= 10;
			num += buffer[i] - '0';
		}
		else {
			dmx.frames[dmx_frame++] = num;
			num = 0;
		}
	}
	dmx.frames[dmx_frame++] = num;
	return true;
}

int main(void)
{
	arch.setup();
	gpio.setup();
	kout.setup();
	kin.setup();

	for (unsigned char i = 0; i < dmx.num_frames; i++) {
		dmx.frames[i] = i*5;
	}

	/*
	 * lowest supported frequency: 62 Hz
	 * timer_running = 16 → actual frequency 4 Hz
	 */
	timer.setup_hz(64);
	timer.start(1);

#if DEBUG
	kout << "Ready" << endl;
#endif

	while (1) {
		while (timer_running) {
			arch.idle();
			while (kin.hasKey()) {
				char key = kin.getKey();
				if ((key >= ' ') && (key <= '~')) {
					buffer[buf_pos++] = key;
				}
#if DEBUG
				kout << key << flush;
#endif

				if (buf_pos >= sizeof(buffer)) {
					buf_pos = 0;
				}

				if (buf_pos && ((key == '\n') || (key == '\r'))) {
					buffer[buf_pos] = 0;
					if (input_to_dmx()) {
#if DEBUG
						kout << endl << "DMX: ";
						for (unsigned char i = 1; i < dmx.num_frames; i++) {
							kout << dmx.frames[i] << " ";
						}
						kout << endl << "> " << flush;
#endif
					}
					buf_pos = 0;
				}
			}
		}
		gpio.led_toggle(1);
		timer.stop();
		timer_running = 16;
		timer.start(1);

		kin.disable();
		dmx.setup();
		dmx.write();
		kout.setup();
		kin.setup();
	}

	return 0;
}

ON_TIMER_INTERRUPT_head
	if (timer_running) {
		timer_running--;
	}
ON_TIMER_INTERRUPT_tail