Working on the final Space Rocks (i)

The components for the second two Space Rocks needed to take up less space. In the case of Undarum, the amplifier was too large. Shown here is the circuit on a new PCB (version 3) using an Adafruit Mono 2.5W Class D Audio Amplifier (PAM8302), which has a much smaller footprint and height than the previous self-assembly amplifier kit I was using.

Adafruit Mono 2.5W Class D Audio Amplifier (PAM8302)
Adafruit Mono 2.5W Class D Audio Amplifier (PAM8302)
Adafruit Mono 2.5W Class D Audio Amplifier (PAM8302), speaker and PCB
Adafruit Mono 2.5W Class D Audio Amplifier (PAM8302), speaker and PCB
Adafruit Mono 2.5W Class D Audio Amplifier (PAM8302), speaker and PCB in action

Printed Circuit Boards

Finally had the chance to work out how to create the files for the PCB to go inside the Space Rocks, using KiCAD, and with much help from @cunabula.

The files have now been sent away to be printed, and I eagerly await being able to test them in situ in a few weeks’ time.

Some new inspiration

A few links of interest for the start of the year, and the next phase of version 1 of the Space Rocks.

Using voice to navigate digital products
Adobe XD uses voice commands to seamlessly integrate voice into prototyping workflows so that designers can be involved in the early creation stages of voice applications.
Adobe XD voice prototyping
.

openFrameworks
An open source C++ toolkit for creative coding. Thanks to @cunabula for the link.
https://openframeworks.cc

Free sounds from the Polish Radio Experimental Studio
Something for when I get some time to play with Ableton. A fascinating story, too:
Free sounds from the Polish Radio Experimental Studio – Ableton

One of the first institutions in Europe dedicated to experimental and electronic music, founded in Poland. Set up in 1957 to create musical ‘illustrations’ for movies, radio and television, Polish Radio Experimental Studio (PRES) was an island of artistic freedom throughout the 1960s, 70s and 80s. As one of the few studios in Eastern Europe with electronic music equipment, and crucially, engineers who could service it, the PRES was a center of research into the possibilities of tape music and saw the creation of many astonishing original electro-acoustic works.

Depending on how paranoid you are, this research from Stanford and Google will be either terrifying or fascinating. A machine learning agent intended to transform aerial images into street maps and back was found to be cheating by hiding information it would need later in “a nearly imperceptible, high-frequency signal.”
This clever AI hid data from its creators to cheat at its appointed task

A few trends in what our industry is writing, talking, and thinking about. Here’s what to expect for UX in 2019.
The State of UX in 2019

And following on from that, this book – Calm technology by Amber Case

 

Ugly Duck exhibition for PG degree show, September 2018

Photos of the Ugly Duck exhibition for the Ravensbourne Postgraduate final degree show. 19th-21st September 2018

Current code for Space Rocks

Here’s the current code for each Space Rock and the transmitter that they connect to. The code allows the synth programmed into each Rock to change based on the relative distance to the transmitter.

Vaporum (‘Small whale’)
Uses the Control Echo Theremin (Mozzi) synth

// include all libraries
#include <LoRaLib.h>
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h>
#include <ControlDelay.h>
#include <RollingAverage.h>

// uncomment the following line for debug output
// NOTE: debug output will slow down Arduino!
//#define DEBUG

#ifdef DEBUG
  #define DEBUG_BEGIN(x)                Serial.begin (x)
  #define DEBUG_PRINT(x)                Serial.print (x)
  #define DEBUG_PRINT_DEC(x)            Serial.print (x, DEC)
  #define DEBUG_PRINT_HEX(x)            Serial.print (x, HEX)
  #define DEBUG_PRINTLN(x)              Serial.println (x)
  #define DEBUG_PRINT_STR(x)            Serial.print (F(x))
  #define DEBUG_PRINTLN_STR(x)          Serial.println (F(x))
#else
  #define DEBUG_BEGIN(x)
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINT_DEC(x)
  #define DEBUG_PRINT_HEX(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT_STR(x)
  #define DEBUG_PRINTLN_STR(x)
#endif

// Mozzi control rate in Hz
#define CONTROL_RATE              512

// RSSI range bounds
#define RSSI_LOW                  -60
#define RSSI_HIGH                 -30

// freqency range bounds in Hz
#define FREQ_LOW                  0
#define FREQ_HIGH                 1000

// SX1278 object instance
SX1278 lora = new LoRa;

// rolling average filter 
RollingAverage <float, 32> kAverage;

// theremin effect echo cells
unsigned int echo_cells_1 = 32;
unsigned int echo_cells_2 = 60;
unsigned int echo_cells_3 = 127;

// 2 second delay
ControlDelay <128, int> kDelay;

// oscils to compare bumpy to averaged control input
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin0(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin1(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin2(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin3(SIN2048_DATA);

void setup(){
  // start Serial port for debugging
  DEBUG_BEGIN(115200);

  // initialize SX1278
  int state = lora.begin();
  DEBUG_PRINTLN(state);

  // set LoRa bandwidth
  state = lora.setBandwidth(250);
  DEBUG_PRINTLN(state);

  // set interrupt action
  lora.setDio0Action(setFlag);

  // start listening for LoRa transmissions
  lora.startReceive();

  // start Mozzi
  startMozzi(CONTROL_RATE);

  // set echo cells
  kDelay.set(echo_cells_1);
}

// flag to indicate that a packet was received
volatile bool receivedFlag = false;

// disable interrupt when it's not needed
volatile bool enableInterrupt = true;

void setFlag(void) {
  // check if the interrupt is enabled
  if(!enableInterrupt) {
    return;
  }

  // we got a packet, set the flag
  receivedFlag = true;
}

void updateControl(){
  // check if packet was received
  if(receivedFlag) {
    // disable the interrupt service routine while processing the data
    enableInterrupt = false;

    // reset flag
    receivedFlag = false;

    // read packet and update RSSI reading
    String str;
    lora.readData(str);

    // get raw RSSI value
    int rssiRaw = lora.lastPacketRSSI;

    // map raw RSSI value to frequency range
    int rssiMapped = map(rssiRaw, RSSI_LOW, RSSI_HIGH, FREQ_LOW, FREQ_HIGH);

    // filter frequency value
    float freqFiltered = kAverage.next(rssiMapped);

    // print RSSI values for debugging
    DEBUG_PRINT(rssiRaw);
    DEBUG_PRINT('\t');
    DEBUG_PRINT(rssiMapped);
    DEBUG_PRINT('\t');
    DEBUG_PRINTLN(freqFiltered);

    // set new frequency
    aSin0.setFreq(freqFiltered);
    aSin1.setFreq(kDelay.next(freqFiltered));
    aSin2.setFreq(kDelay.read(echo_cells_2));
    aSin3.setFreq(kDelay.read(echo_cells_3));

    // enable interrupt again
    enableInterrupt = true;
  }
}

int updateAudio(){
  return 3 * ((int)aSin0.next() + aSin1.next() + (aSin2.next() >> 1) + (aSin3.next() >> 2)) >> 3;
}

void loop(){
  audioHook();
}


Cognitum (‘Razor clam’)
Uses the Detuned Beats Wash (Mozzi) synth

// include all libraries
#include <LoRaLib.h>
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <mozzi_fixmath.h>
#include <RollingAverage.h>

// uncomment the following line for debug output
// NOTE: debug output will slow down Arduino!
//#define DEBUG

#ifdef DEBUG
  #define DEBUG_BEGIN(x)                Serial.begin (x)
  #define DEBUG_PRINT(x)                Serial.print (x)
  #define DEBUG_PRINT_DEC(x)            Serial.print (x, DEC)
  #define DEBUG_PRINT_HEX(x)            Serial.print (x, HEX)
  #define DEBUG_PRINTLN(x)              Serial.println (x)
  #define DEBUG_PRINT_STR(x)            Serial.print (F(x))
  #define DEBUG_PRINTLN_STR(x)          Serial.println (F(x))
#else
  #define DEBUG_BEGIN(x)
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINT_DEC(x)
  #define DEBUG_PRINT_HEX(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT_STR(x)
  #define DEBUG_PRINTLN_STR(x)
#endif

// Mozzi control rate in Hz
#define CONTROL_RATE              512

// RSSI range bounds
#define RSSI_LOW                  -60
#define RSSI_HIGH                 -30

// freqency range bounds in Hz
#define FREQ_LOW                  0
#define FREQ_HIGH                 1000

// SX1278 object instance
SX1278 lora = new LoRa;

// rolling average filter 
RollingAverage <float, 32> kAverage;

// harmonics
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos1(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos2(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos3(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos4(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos5(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos6(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos7(COS8192_DATA);

// duplicates but slightly off frequency for adding to originals
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos1b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos2b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos3b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos4b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos5b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos6b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos7b(COS8192_DATA);

// base pitch frequencies in 24n8 fixed int format (for speed later)
Q16n16 f1,f2,f3,f4,f5,f6,f7;

Q16n16 variation() {
  // 32 random bits & with 524287 (b111 1111 1111 1111 1111)
  // gives between 0-8 in Q16n16 format
  return  (Q16n16) (xorshift96() & 524287UL);
}

void setup(){
  // start Serial port for debugging
  DEBUG_BEGIN(115200);

  // initialize SX1278
  int state = lora.begin();
  DEBUG_PRINTLN(state);

  // set LoRa bandwidth
  state = lora.setBandwidth(250);
  DEBUG_PRINTLN(state);

  // set interrupt action
  lora.setDio0Action(setFlag);

  // start listening for LoRa transmissions
  lora.startReceive();

  // start Mozzi
  startMozzi(CONTROL_RATE);

  // select base frequencies using mtof (midi to freq) and fixed-point numbers
  f1 = Q16n16_mtof(Q16n0_to_Q16n16(48));
  f2 = Q16n16_mtof(Q16n0_to_Q16n16(74));
  f3 = Q16n16_mtof(Q16n0_to_Q16n16(64));
  f4 = Q16n16_mtof(Q16n0_to_Q16n16(77));
  f5 = Q16n16_mtof(Q16n0_to_Q16n16(67));
  f6 = Q16n16_mtof(Q16n0_to_Q16n16(57));
  f7 = Q16n16_mtof(Q16n0_to_Q16n16(60));

  // set Oscils with chosen frequencies
  aCos1.setFreq_Q16n16(f1);
  aCos2.setFreq_Q16n16(f2);
  aCos3.setFreq_Q16n16(f3);
  aCos4.setFreq_Q16n16(f4);
  aCos5.setFreq_Q16n16(f5);
  aCos6.setFreq_Q16n16(f6);
  aCos7.setFreq_Q16n16(f7);

  // set frequencies of duplicate oscillators
  aCos1b.setFreq_Q16n16(f1 + variation());
  aCos2b.setFreq_Q16n16(f2 + variation());
  aCos3b.setFreq_Q16n16(f3 + variation());
  aCos4b.setFreq_Q16n16(f4 + variation());
  aCos5b.setFreq_Q16n16(f5 + variation());
  aCos6b.setFreq_Q16n16(f6 + variation());
  aCos7b.setFreq_Q16n16(f7 + variation());
}

// flag to indicate that a packet was received
volatile bool receivedFlag = false;

// disable interrupt when it's not needed
volatile bool enableInterrupt = true;

void setFlag(void) {
  // check if the interrupt is enabled
  if(!enableInterrupt) {
    return;
  }

  // we got a packet, set the flag
  receivedFlag = true;
}

void updateControl(){
  // check if packet was received
  if(receivedFlag) {
    // disable the interrupt service routine while processing the data
    enableInterrupt = false;

    // reset flag
    receivedFlag = false;

    // read packet and update RSSI reading
    String str;
    lora.readData(str);

    // get raw RSSI value
    int rssiRaw = lora.lastPacketRSSI;

    // map raw RSSI value to frequency range
    int rssiMapped = map(rssiRaw, RSSI_LOW, RSSI_HIGH, FREQ_LOW, FREQ_HIGH);

    // filter frequency value
    float freqFiltered = kAverage.next(rssiMapped);

    // print RSSI values for debugging
    DEBUG_PRINT(rssiRaw);
    DEBUG_PRINT('\t');
    DEBUG_PRINT(rssiMapped);
    DEBUG_PRINT('\t');
    DEBUG_PRINTLN(freqFiltered);

    // change frequencies of the b oscillators
    switch(lowByte(xorshift96()) & 7) {
      case 0:
        aCos1b.setFreq_Q16n16(f1 + float_to_Q16n16(freqFiltered) + variation());
        break;
      case 1:
        aCos2b.setFreq_Q16n16(f2 + float_to_Q16n16(freqFiltered) + variation());
        break;
      case 2:
        aCos3b.setFreq_Q16n16(f3 + float_to_Q16n16(freqFiltered) + variation());
        break;
      case 3:
        aCos4b.setFreq_Q16n16(f4 + float_to_Q16n16(freqFiltered) + variation());
        break;
      case 4:
        aCos5b.setFreq_Q16n16(f5 + float_to_Q16n16(freqFiltered) + variation());
        break;
      case 5:
        aCos6b.setFreq_Q16n16(f6 + float_to_Q16n16(freqFiltered) + variation());
        break;
      case 6:
        aCos7b.setFreq_Q16n16(f7 + float_to_Q16n16(freqFiltered) + variation());
        break;
    }

    // enable interrupt again
    enableInterrupt = true;
  }
}

int updateAudio(){
  int asig =
    aCos1.next() + aCos1b.next() +
    aCos2.next() + aCos2b.next() +
    aCos3.next() + aCos3b.next() +
    aCos4.next() + aCos4b.next() +
    aCos5.next() + aCos5b.next() +
    aCos6.next() + aCos6b.next() +
    aCos7.next() + aCos7b.next();

  return asig >> 3;
}

void loop(){
  audioHook();
}


Undarum (‘Wide shell’)

Uses the Knob Light (Mozzi) synth

// include all libraries
#include <LoRaLib.h>
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h>
#include <RollingAverage.h>

// uncomment the following line for debug output
// NOTE: debug output will slow down Arduino!
//#define DEBUG

#ifdef DEBUG
  #define DEBUG_BEGIN(x)                Serial.begin (x)
  #define DEBUG_PRINT(x)                Serial.print (x)
  #define DEBUG_PRINT_DEC(x)            Serial.print (x, DEC)
  #define DEBUG_PRINT_HEX(x)            Serial.print (x, HEX)
  #define DEBUG_PRINTLN(x)              Serial.println (x)
  #define DEBUG_PRINT_STR(x)            Serial.print (F(x))
  #define DEBUG_PRINTLN_STR(x)          Serial.println (F(x))
#else
  #define DEBUG_BEGIN(x)
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINT_DEC(x)
  #define DEBUG_PRINT_HEX(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT_STR(x)
  #define DEBUG_PRINTLN_STR(x)
#endif

// Mozzi control rate in Hz
#define CONTROL_RATE              512

// RSSI range bounds
#define RSSI_LOW                  -60
#define RSSI_HIGH                 -30

// freqency range bounds in Hz
#define FREQ_LOW                  400
#define FREQ_HIGH                 800

// SX1278 object instance
SX1278 lora = new LoRa;

// rolling average filter 
RollingAverage <float, 32> kAverage;

// Mozzi oscillators
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCarrier(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aModulator(COS2048_DATA);

 // harmonics
int mod_ratio = 3;

 // carries control info from updateControl() to updateAudio()
long fm_intensity;

void setup(){
  // start Serial port for debugging
  DEBUG_BEGIN(115200);

  // initialize SX1278
  int state = lora.begin();
  DEBUG_PRINTLN(state);

  // set LoRa bandwidth
  state = lora.setBandwidth(250);
  DEBUG_PRINTLN(state);

  // set interrupt action
  lora.setDio0Action(setFlag);

  // start listening for LoRa transmissions
  lora.startReceive();

  // start Mozzi
  startMozzi(CONTROL_RATE);
}

// flag to indicate that a packet was received
volatile bool receivedFlag = false;

// disable interrupt when it's not needed
volatile bool enableInterrupt = true;

void setFlag(void) {
  // check if the interrupt is enabled
  if(!enableInterrupt) {
    return;
  }

  // we got a packet, set the flag
  receivedFlag = true;
}

void updateControl(){
  // check if packet was received
  if(receivedFlag) {
    // disable the interrupt service routine while processing the data
    enableInterrupt = false;

    // reset flag
    receivedFlag = false;

    // read packet and update RSSI reading
    String str;
    lora.readData(str);

    // get raw RSSI value
    int rssiRaw = lora.lastPacketRSSI;

    // map raw RSSI value to frequency range
    int rssiMapped = map(rssiRaw, RSSI_LOW, RSSI_HIGH, FREQ_LOW, FREQ_HIGH);

    // filter frequency value
    float freqFiltered = kAverage.next(rssiMapped);

    // print RSSI values for debugging
    DEBUG_PRINT(rssiRaw);
    DEBUG_PRINT('\t');
    DEBUG_PRINT(rssiMapped);
    DEBUG_PRINT('\t');
    DEBUG_PRINTLN(freqFiltered);

    // set new frequency
    aCarrier.setFreq(freqFiltered); 
    aModulator.setFreq(freqFiltered * mod_ratio);
    fm_intensity = freqFiltered;

    // enable interrupt again
    enableInterrupt = true;
  }
}

int updateAudio(){
  long modulation = fm_intensity * aModulator.next(); 
  return aCarrier.phMod(modulation);
}

void loop(){
  audioHook();
}


Marginis (‘Shape 4’)

Uses the Sine Wave Pulse (Mozzi) synth

// include all libraries
#include <LoRaLib.h>
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h>
#include <Smooth.h>
#include <RollingAverage.h>

// uncomment the following line for debug output
// NOTE: debug output will slow down Arduino!
//#define DEBUG

#ifdef DEBUG
  #define DEBUG_BEGIN(x)                Serial.begin (x)
  #define DEBUG_PRINT(x)                Serial.print (x)
  #define DEBUG_PRINT_DEC(x)            Serial.print (x, DEC)
  #define DEBUG_PRINT_HEX(x)            Serial.print (x, HEX)
  #define DEBUG_PRINTLN(x)              Serial.println (x)
  #define DEBUG_PRINT_STR(x)            Serial.print (F(x))
  #define DEBUG_PRINTLN_STR(x)          Serial.println (F(x))
#else
  #define DEBUG_BEGIN(x)
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINT_DEC(x)
  #define DEBUG_PRINT_HEX(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT_STR(x)
  #define DEBUG_PRINTLN_STR(x)
#endif

// Mozzi control rate in Hz
#define CONTROL_RATE              512

// RSSI range bounds
#define RSSI_LOW                  -60
#define RSSI_HIGH                 -30

// freqency range bounds in Hz
#define FREQ_LOW                  400
#define FREQ_HIGH                 800

// SX1278 object instance
SX1278 lora = new LoRa;

// rolling average filter 
RollingAverage <float, 32> kAverage;

// Mozzi sine oscillator
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);

// target gain for smoothing, toggle between 255/0
byte gain = 0;

// Smoothing filter, higher number = smoother output
Smooth <long> aSmoothGain(0.9995);

void setup() {
  // start Serial port for debugging
  DEBUG_BEGIN(115200);

  // initialize SX1278
  int state = lora.begin();
  DEBUG_PRINTLN(state);

  // set LoRa bandwidth
  state = lora.setBandwidth(250);
  DEBUG_PRINTLN(state);

  // set interrupt action
  lora.setDio0Action(setFlag);

  // start listening for LoRa transmissions
  lora.startReceive();

  // start Mozzi
  startMozzi(CONTROL_RATE);

  // set output frequency to the lowest value
  aSin.setFreq(FREQ_LOW);
}

// flag to indicate that a packet was received
volatile bool receivedFlag = false;

// disable interrupt when it's not needed
volatile bool enableInterrupt = true;

void setFlag(void) {
  // check if the interrupt is enabled
  if(!enableInterrupt) {
    return;
  }

  // we got a packet, set the flag
  receivedFlag = true;
}

// variable to save starting timestamp
unsigned long start = 0;

// delay length in microseconds
unsigned long delayMicros = FREQ_LOW * 1000;

void updateControl() {
  // check if packet was received
  if(receivedFlag) {
    // disable the interrupt service routine while processing the data
    enableInterrupt = false;

    // reset flag
    receivedFlag = false;

    // read packet and update RSSI reading
    String str;
    lora.readData(str);

    // get raw RSSI value
    int rssiRaw = lora.lastPacketRSSI;

    // map raw RSSI value to frequency range
    int rssiMapped = map(rssiRaw, RSSI_LOW, RSSI_HIGH, FREQ_LOW, FREQ_HIGH);

    // filter frequency value
    float freqFiltered = kAverage.next(rssiMapped);

    // print RSSI values for debugging
    DEBUG_PRINT(rssiRaw);
    DEBUG_PRINT('\t');
    DEBUG_PRINT(rssiMapped);
    DEBUG_PRINT('\t');
    DEBUG_PRINTLN(freqFiltered);

    // set new frequency
    aSin.setFreq(freqFiltered);

    // set new delay length
    delayMicros = (FREQ_HIGH - freqFiltered) * 1000;

    // check if it's time to pulse
    if(mozziMicros() - start >= delayMicros) {
      // save current time
      start = mozziMicros();

      // flip 0/255
      gain = 255 - gain;
    }

    // enable interrupt again
    enableInterrupt = true;
  }
}

int updateAudio(){
  return (aSmoothGain.next(gain) * aSin.next()) >> 8 ;
}

void loop() {
  audioHook();
}

And the code for the transmitter, which links the four Space Rocks together.

// include library
#include <LoRaLib.h>

// SX1278 object instance
SX1278 lora = new LoRa;

void setup() {
  // start Serial port for debugging
  Serial.begin(115200);
  
  // initialize SX1278
  Serial.println(lora.begin());

  // set LoRa bandwidth
  Serial.println(lora.setBandwidth(250));

  // set output power to limit jamming
  Serial.println(lora.setOutputPower(5));
}

void loop() {
  // transmit packets as fast as we can
  lora.transmit("WeAreHere");
}