Skip to content

Commit

Permalink
Misc tweaks (#24)
Browse files Browse the repository at this point in the history
A few miscellaneous changes / fixes:
* Allow Lua scripts to write to the 3x output lines on the accessory port
* Allow Lua scripts to set 0 pulse width, i.e. generate only one polarity. Previously 1us was the minimum
* Fix issue where the channel 1 bar graph would briefly show around 50% on power up
* Fix bug in toggle pattern where turning the adjust dial with the 'Pulse/Cont.' parameter selected would trigger a swap to the next channel
* Tweak toggle so that the default speed is somewhere near the middle, rather than the slowest speed
  • Loading branch information
CrashOverride85 authored May 12, 2023
1 parent 1513d7b commit c6d8478
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 21 deletions.
33 changes: 27 additions & 6 deletions docs/LuaNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ There are a few example scripts in `remote_access/lua`, which demonstrate some o

* waves.lua - a waves pattern that is slightly more advanced than the inbuilt one. For each channel, this varies the frequency between 25Hz and 250Hz and the pulse width between 40us and 200us, with the time taken for each cycle being set per channel on the menu.

* acc_test.lua - uses the accessory port to cycle between HIGH/LOW on the 3 output lines. See "AccIoWrite" section below for more details. Doesn't produce any estim output, so not really of any practical use, just a demo of how to use the accessory port.

## toggle.lua

It's probably easier to explain Lua as implemented in the ZC95 by going though one of the example scripts.
Expand All @@ -31,9 +33,9 @@ Config = {
id = 1,
min = 100,
max = 2000,
increment_step = 100,
increment_step = 100,
uom = "ms",
default = _delay_ms
default = _delay_ms
},
{
type = "MULTI_CHOICE",
Expand Down Expand Up @@ -121,9 +123,9 @@ Config = {
id = 1,
min = 100,
max = 2000,
increment_step = 100,
increment_step = 100,
uom = "ms",
default = _delay_ms
default = _delay_ms
},
{
type = "MULTI_CHOICE",
Expand Down Expand Up @@ -245,8 +247,8 @@ Sets the output frequency of the specified channel. Currently defaults to 150Hz,
```
Params:
* channel number (1-4)
* positive pulse width (1-255) us
* negative pulse width (1-255) us
* positive pulse width (0-255) us
* negative pulse width (0-255) us
```
Sets the pulse width used for the channel, defaults to 150us, but this default may move into the config menus at some point.
For symmetric pulses (as used by most/all inbuilt patterns), these two values should be the same.
Expand Down Expand Up @@ -274,6 +276,23 @@ Params:
```
Switch off the specified channel.

### AccIoWrite
```
Params:
* Accessory I/O line number (1-3)
* State: true (high) or false (low)
```
Controls the 3 I/O lines on the accessory port - allows setting between high (3.3v) and low.

Note that the default state of these 3 lines from power on is HIGH, so bear that in mind when connecting anything.
These lines can only source a few milliamps safely, so should only be used for signalling, i.e. it's probably best to connect a logic level MOSFET to switch anything more substantial than an LED.

Also worth noting that there is _very_ limited protection on this port, something to be corrected in a possible future hardware revision, so be careful to avoid higher voltages. In particular, there is 12v on pin 7 (in hindsight a poor decision) - connecting this to pretty much any other pin would be bad.

Minimal example for using the accessory port to control 3 LEDs. Can be used with the "acc_test.lua" example LUA script to switch between each LED in turn.

![acc port]


## Special functions
These are functions that will be automatically called when applicable whilst the Lua script is running. With the exception of `Loop()`, all are optional.
Expand All @@ -299,3 +318,5 @@ Called once when the pattern is started, before `Loop()`. It can be used to do a

### Loop(time_ms)
Called periodically for as long as the pattern is running. `time_ms` is how long in milliseconds the box has been powered on.

[acc port]: images/lua_acc_port.png "Accessory port"
Binary file added docs/images/lua_acc_port.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion source/zc95/AudioInput/CAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ uint16_t CAudio::get_bar_height(float sample)

void CAudio::do_fft(uint16_t sample_count, uint8_t *buffer)
{
// The FFT logic is slow, and as it's essentially just number crunching (no I/O), it's safe to interupt
// The FFT logic is slow, and as it's essentially just number crunching (no I/O), it's safe to interrupt
_interuptable_section.start();

// These are too big to put on the stack, especially with the recursion used by ESP_fft
Expand Down
16 changes: 12 additions & 4 deletions source/zc95/FpKnobs/CFrontPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define ROT_B 7

/*
* Front pannel which has 4x potentiometers conencted to an I2C ADC,
* Front panel which has 4x potentiometers connected to an I2C ADC,
* and 1x rotary encoder connected to an I2C port expander
*/

Expand All @@ -16,9 +16,14 @@ CFrontPanel::CFrontPanel(CSavedSettings *saved_settings)
memset(_power_level, 0, sizeof(_power_level));
_last_port_exp_read = 0;
_adjust_value = 0;

// The very first time the ADC is read, the first channel seems to have an invalid value. So read it now,
// so when it's read next time as usual, it'll return something sensible.
// This is just to stop the channel 1 bar graph briefly (fraction of a second) showing ~50% power on startup
read_adc();
}

void CFrontPanel::interupt (port_exp exp)
void CFrontPanel::interrupt (port_exp exp)
{
_interrupt = true;
_interrupt_time = time_us_32();
Expand All @@ -36,8 +41,11 @@ void CFrontPanel::process(bool always_update)
//printf("delay=%lu us\n", time_us_32() - _interrupt_time);
_interrupt = false;
}
else

if (always_update)
{
read_adc();
}

uint8_t buffer;
buffer = read_port_expander();
Expand Down Expand Up @@ -82,7 +90,7 @@ void CFrontPanel::read_adc()
return;
}

uint8_t buffer[5];
uint8_t buffer[5] = {0};
int retval = i2c_read(__func__, ADC_ADDR, buffer, sizeof(buffer), false);
if (retval == PICO_ERROR_GENERIC || retval == PICO_ERROR_TIMEOUT)
{
Expand Down
2 changes: 1 addition & 1 deletion source/zc95/FpKnobs/CFrontPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CFrontPanel
void process(bool always_update);
uint16_t get_channel_power_level(uint8_t channel);
int8_t get_adjust_control_change();
void interupt (port_exp exp);
void interrupt (port_exp exp);

private:
void read_adc();
Expand Down
34 changes: 29 additions & 5 deletions source/zc95/core1/routines/CLuaRoutine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

typedef int (CLuaRoutine::*mem_func)(lua_State * L);

// Copied / adpated from https://stackoverflow.com/a/32416597
// Copied / adapted from https://stackoverflow.com/a/32416597
template <mem_func func> int dispatch(lua_State *L)
{
if (L->l_G->ud)
Expand Down Expand Up @@ -110,6 +110,7 @@ void CLuaRoutine::load_lua_script_if_required()
{ "SetPower" , &dispatch<&CLuaRoutine::lua_set_power> },
{ "SetFrequency" , &dispatch<&CLuaRoutine::lua_set_freq> },
{ "SetPulseWidth" , &dispatch<&CLuaRoutine::lua_set_pulse_width> },
{ "AccIoWrite" , &dispatch<&CLuaRoutine::lua_acc_io_write> },
{ NULL, NULL }
};
luaL_register(_lua_state, "zc", zc_regs);
Expand Down Expand Up @@ -633,19 +634,42 @@ int CLuaRoutine::lua_set_freq(lua_State *L)

// Params:
// int: channel number (1-4)
// int: positive pulse width (1-255) us
// int: negative pulse width (1-255) us
// int: positive pulse width (0-255) us
// int: negative pulse width (0-255) us
int CLuaRoutine::lua_set_pulse_width(lua_State *L)
{
int chan = lua_tointeger(L, 1);
int pos = lua_tointeger(L, 2);
int neg = lua_tointeger(L, 3);

if (!is_channel_number_valid(chan)) return 0;
if (pos <= 0 || pos > 255) return 0;
if (neg <= 0 || neg > 255) return 0;
if (pos < 0 || pos > 255) return 0;
if (neg < 0 || neg > 255) return 0;

full_channel_set_pulse_width(chan-1, pos, neg);
return 1;
}

// Params:
// int : Accessory port I/O line (1-3)
// bool: State - true=High, false=Low
int CLuaRoutine::lua_acc_io_write(lua_State *L)
{
int io_line = lua_tointeger(L, 1);
bool state = lua_toboolean(L, 2);

ExtInputPort io_port;
switch (io_line)
{
case 1: io_port = ExtInputPort::ACC_IO_1; break;
case 2: io_port = ExtInputPort::ACC_IO_2; break;
case 3: io_port = ExtInputPort::ACC_IO_3; break;
default:
return 0;
}

acc_port.set_io_port_state(io_port, state);

return 1;
}

1 change: 1 addition & 0 deletions source/zc95/core1/routines/CLuaRoutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class CLuaRoutine: public CRoutine
int lua_set_power(lua_State *L);
int lua_set_freq(lua_State *L);
int lua_set_pulse_width(lua_State *L);
int lua_acc_io_write(lua_State *L);

lua_State *_lua_state;
ScriptValid _script_valid = ScriptValid::UNKNOWN;
Expand Down
14 changes: 12 additions & 2 deletions source/zc95/core1/routines/CToggle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ enum menu_ids
CToggle::CToggle(uint8_t param)
{
printf("CToggle()\n");
_speed_setting = 500;
_speed_setting = 2000;
}

CToggle::~CToggle()
Expand All @@ -54,7 +54,7 @@ void CToggle::config(struct routine_conf *conf)
menu_speed.minmax.increment_step = 50; // 3500 (max-min) steps is a bit much, increment by 50 each time to give 70 steps
menu_speed.minmax.min = 500;
menu_speed.minmax.max = 4000;
menu_speed.minmax.current_value = 500; // start at the slowest speed
menu_speed.minmax.current_value = 2000; // start somewhere near the middle
conf->menu.push_back(menu_speed);

// menu entry 2: "pulse/cont." - pulse each channel, or toggle between each?
Expand Down Expand Up @@ -83,6 +83,16 @@ void CToggle::menu_min_max_change(uint8_t menu_id, int16_t new_value)

void CToggle::menu_multi_choice_change(uint8_t menu_id, uint8_t choice_id)
{
// If no change exit
if
(
(choice_id == 1 && _pulse_mode) ||
(choice_id == 0 && !_pulse_mode)
)
{
return;
}

if (menu_id == menu_ids::PULSE_CONT)
{
// Switch off before changing mode
Expand Down
4 changes: 2 additions & 2 deletions source/zc95/zc95.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ void gpio_callback(uint gpio, uint32_t events)
else if (gpio == PIN_FP_INT1)
{
if (_front_pannel != NULL)
_front_pannel->interupt(CFrontPanel::port_exp::U1);
_front_pannel->interrupt(CFrontPanel::port_exp::U1);
}
else if (gpio == PIN_FP_INT2)
{
if (_front_pannel != NULL)
_front_pannel->interupt(CFrontPanel::port_exp::U2);
_front_pannel->interrupt(CFrontPanel::port_exp::U2);
}
}

Expand Down

0 comments on commit c6d8478

Please sign in to comment.