Pages: [1]   Go Down

Author Topic: RadioFruit Arduino boards Legality Thoughts and Questions  (Read 576 times)

AF7JA

  • Member
  • Posts: 302
RadioFruit Arduino boards Legality Thoughts and Questions
« on: November 26, 2022, 11:29:38 AM »

A saw a project in last months Make magazine which involved using an Arduino to display on a 16x16 LED panel. The article was "Long Distance Aloji Lamp" in Volume 83. It gave me an idea and I want to have some of my more advanced students work on it.

Keep in mind, I teach at a Middle School in an underperforming Title 1 (poverty) district. I am not being negative. That is just the reality that I am in. Less than 1 in a hundred of the students' at my school are even interested in the Arduino based class. However those, that are, are very interested.

My school uses an A, B, T, & O schedule. We alternate A & B schedule days, have state Testing schedule days, and, of course, the all encompassing Other schedule days.

What I want the students to make is a display that will have either an A, B, T, or O displayed in the hall outside of my classes. Yes, through labourious design, this could be done entirely in hardware. However, I want them to do it in software.

The initial design, in Make magazine, calls for all of the displays to talk to one another using 433mhz Arduino Boards. In that design, if one unit is changed, then all of the others change. As an example, if I were to change the unit in my classroom, it would change the unit in the hallway.

Not wanting the chaos of students regularly changing the display, I want the students to alter the design in the magazine to place a single transmitter on my desk, and the displays to have receive only functionality. I don't see this as being particularly hard. I have already worked out the code to make this happen. Of course, the students will need to come up with their own.

Then came the sudden thought about legality. these boards transmit on either 915mhz or 433mhz.

Do I need to send my callsign and can someone else legally change the display, which would result in a radio emission to the displays?

I can think of a way to do that, such as sending my callsign in a print command to a device without the ability to use that data. However, the data has been sent. . . does that meet the station identification requirements?

How are the Radio Control pilots meeting the station identification requirements?
The information mentions the ability to use packet control libraries, is there something that I am likely to find in those libraries (note, libraries refers to a "thing" in the C programming language)

Here is some information about the boards:
Quote
  • Measures 2.0" x 0.9" x 0.3" (51mm x 23mm x 8mm) without headers soldered in
  • Light as a (large?) feather - 5.8 grams
  • ATSAMD21G18 @ 48MHz with 3.3V logic/power
  • No EEPROM
  • 3.3V regulator with 500mA peak current output
  • USB native support, comes with USB bootloader and serial port debugging
  • You also get tons of pins - 20 GPIO pins
  • Hardware Serial, hardware I2C, hardware SPI support
  • 8 x PWM pins
  • 10 x analog inputs
  • 1 x analog output
  • Built in 100mA lipoly charger with charging status indicator LED
  • Pin #13 red LED for general purpose blinking
  • Power/enable pin
  • 4 mounting holes
  • Reset button
  • SX127x LoRa® based module with SPI interface
  • Packet radio with ready-to-go Arduino libraries
  • Uses the license-free ISM bands (ITU "Europe" @ 433MHz and ITU "Americas" @ 900MHz)
  • +5 to +20 dBm up to 100 mW Power Output Capability (power output selectable in software)
  • ~300uA during full sleep, ~120mA peak during +20dBm transmit, ~40mA during active radio listening.
  • Simple wire antenna or spot for uFL connector
Logged

W1VT

  • Member
  • Posts: 6071
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #1 on: November 26, 2022, 11:51:16 AM »

§97.215   Telecommand of model craft.

An amateur station transmitting signals to control a model craft may be operated as follows:

(a) The station identification procedure is not required for transmissions directed only to the model craft, provided that a label indicating the station call sign and the station licensee's name and address is affixed to the station transmitter.

(b) The control signals are not considered codes or ciphers intended to obscure the meaning of the communication.

(c) The transmitter power must not exceed 1 W.

There is no Part 15 allocation at 433MHz, but unlicensed key fobs at 433MHz are used in the UK.  Part 15 rules are quite complex with lots of grandfathered usages.
There is a Part 15 allocation at 33cm.

Off the shelf 2.4GHz spread spectrum has largely made ham Radio Control obsolete, but FPV drone users often need the higher power allowed to hams to transmit video over the distances they need.
Similarly, those building expensive high powered rockets often want long distance tracking transmitters and will get their ham license to use them legally.
https://shop.bigredbee.com/
« Last Edit: November 26, 2022, 11:56:16 AM by W1VT »
Logged

AF7JA

  • Member
  • Posts: 302
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #2 on: November 26, 2022, 11:56:19 AM »


There is no Part 15 allocation at 433MHz, but unlicensed key fobs at 433MHz are used in the UK.  Part 15 rules are quite complex with lots of grandfathered usages.
There is a Part 15 allocation at 33cm.

Strange, I thought 433 was in the middle of the 70cm band.

I am still charging forward. I think the kids involved will enjoy it.
Logged

W7XTV

  • Member
  • Posts: 1269
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #3 on: November 26, 2022, 12:47:04 PM »


There is no Part 15 allocation at 433MHz, but unlicensed key fobs at 433MHz are used in the UK.  Part 15 rules are quite complex with lots of grandfathered usages.

Strange, I thought 433 was in the middle of the 70cm band.

I am still charging forward. I think the kids involved will enjoy it.

Other than RFID tags, the maximum field strength for 433 MHz (actually, 216-470 and 614-960 MHz) is 200 uV/m at 3 meters.  This calculates to roughly 8 nanowatts into a dipole, a bit less than the 250 uV/m @ 3m allowed on FM broadcast.  This the general radiation limit as stated in 15.209. Anything that could be really useful, with a range of more than about 20 feet, will require a ham license.
Logged
He speaks fluent PSK31, in FT8...  One QSO with him earns you 5BDXCC...  His Wouff Hong has two Wouffs... Hiram Percy Maxim called HIM "The Old Man..."  He is... The Most Interesting Ham In The World!

KD6VXI

  • Member
  • Posts: 1022
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #4 on: November 26, 2022, 12:55:46 PM »

Use Bluetooth or wifi.

Both are license free ISM.

--Shane
WP2ASS / ex KD6VXI
Logged

AF7JA

  • Member
  • Posts: 302
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #5 on: November 26, 2022, 02:08:21 PM »

Use Bluetooth or wifi.

Both are license free ISM.

--Shane
WP2ASS / ex KD6VXI

The distance is too far for bluetooth and, as a teacher, I am not allowed to connect to the school wi-fi. That is limited to school issued devices and administration.

Besides, it provides a good example, for the students, of why other wireless, other than wi-fi and bluetooth are important.
Logged

W6BP

  • Member
  • Posts: 629
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #6 on: November 26, 2022, 02:59:43 PM »

Follow every change-display transmission with your call in Morse; just key the carrier on and off.
Logged

AB6RF

  • Member
  • Posts: 95
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #7 on: November 26, 2022, 07:44:42 PM »

Seems the answer is in your question.  "Americas" @ 900MHz

Use the 900MHz unlicensed band, as the board description suggests, and leave this outside of the licensed ham bands.
Logged

K6JH

  • Member
  • Posts: 701
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #8 on: November 26, 2022, 09:32:33 PM »

https://www.ecfr.gov/current/title-47/chapter-I/subchapter-A/part-15/subpart-C/subject-group-ECFR2f2e5828339709e#p-15.231(a)

47 CFR 15.231 allows use of 433 MHz. At various field strengths and duty cycles depending on exact frequency (linear interpolation in table). Basically if it’s a manually activated signal like a garage door opener you can use the higher limit table, but if you transmit periodically you use the lower field strength table.

If you use 900MHz the limitations on duty cycle are removed. Up to 50mV/meter continuously..
https://www.ecfr.gov/current/title-47/chapter-I/subchapter-A/part-15/subpart-C/subject-group-ECFR2f2e5828339709e#p-15.249(a)

I had the pleasure of designing some part 15 radio devices many years ago. The rules haven’t changed much.
Logged
73
Jim K6JH

KD6VXI

  • Member
  • Posts: 1022
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #9 on: November 27, 2022, 02:03:52 AM »

Use Bluetooth or wifi.

Both are license free ISM.

--Shane
WP2ASS / ex KD6VXI

The distance is too far for bluetooth and, as a teacher, I am not allowed to connect to the school wi-fi. That is limited to school issued devices and administration.

Besides, it provides a good example, for the students, of why other wireless, other than wi-fi and bluetooth are important.

Educate the kids that wifi and Bluetooth are using bands of frequencies, just like am and fm are modes, not bands.

I use a set of Bluetooth headphones when I mow the yard.  I leave my phone in the house simply because  as humid as it is here I would activate a moisture sensor in the phone if I left it in my pocket.

Do what you want.  But I would think educating these kids about bands within the radio spectrum would be somewhat important to.

Don't connect to the school wifi.  Have your own.  2.4 ghz wifi band doesn't mean you have to use an existing wifi access point.

My RC cars use 2.4 ghz wifi bands (I can see it on my spectrum analyzer, I know where they are),  UT have no access point.  My microwave oven, same 2.4 ghz.

Again, great time to educate the kids about the difference between modes, protocols and bands.

--Shane
WP2ASS / ex KD6VXI

Noble project, I wish you all the best.
Logged

W1RKW

  • Member
  • Posts: 219
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #10 on: November 27, 2022, 03:23:07 AM »

nRF24L01 <-- very popular in the Arduino world.
Logged

G4AON

  • Member
  • Posts: 2178
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #11 on: November 28, 2022, 12:15:08 AM »

Here in the UK (and Europe) car key fobs, wireless alarm systems and all manner of other stuff operate on 433 MHz. In fact I have even come across analogue wireless headphones for metal detectors (XP, a French company) that operate on 70cms.

Here it's a bit of a "free for all" on these frequencies. The key fobs operate further than 200 feet!

73 Dave
Logged

AF7JA

  • Member
  • Posts: 302
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #12 on: March 08, 2023, 05:45:04 PM »

. . . and, on the note of the comment above and the fine bit of community it represents, I decided to just leave for a while.

I decided to take a bit of advice from the stoics and just do. With little more on that point. Here is the project in its near final prototype stage. The next step is to solder it up and 3d print the enclosures.

The "problem" to be solved is that the school I teach at has an alternating A/B day schedule. The students, and not a small number of the staff and faculty are frequently asking what day it is. I decided to make a sign that will be at the opposite end of the classroom. Yes, I have a simple paper sign that I have one of the students turn to the correct day. However, there is no task to simple to have complication created in its solution. I decided to make a remote controlled sign.

I will add that, having seen this, several teachers have asked for these in their classrooms. As long as the parts come out of their department budgets, it is great as it can give my students more fabrication practice. Keep in mind, these students are generally seventh and eighth graders who have never soldered, or handled electronic components, before coming to my class.

Here is the sign, it hasn't gone up on the wall yet because I was still playing with the code:

The LED Christmas tree on the file cabinet is an example of the current "learn to solder" projects

This is what it looked like without the glass and defuser. It is sort of funny, in pictures it looks almost the opposite as it does when looking at it in person, the bare panel is almost unreadable in person and the version with the defuser is much easier to read, besides, the defuser gave me a reason to get the art teacher involved.


Here is the controller. The button cycles through the displays. Standby just lights a single LED so I can see that it is on, but isn't bright. After each button press it send the signal to the receivers ten times, then it stops transmitting and the LED goes off.


And, of course, the code. First the transmitter code. I am working on using interrupts instead of having the button detect in a function the way it is. However, these boards a still a bit new to me and I am still working that out.

. . . oops, it looks like that exceeds the allowable post length. I will put the code in the next two posts.
Logged

AF7JA

  • Member
  • Posts: 302
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #13 on: March 08, 2023, 05:47:25 PM »

So, as promised, here is some really ugly code. . . (as I hold up a mangled mess and say, "but I did it myself") This is the transmitter side.

Quote
#include <SPI.h>
#include <RH_RF95.h>
#include <LiquidCrystal_I2C.h> // by Frank de Brabander
int lastPacket;

// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0

// These are used for the button function
const int buttonPin = 12;     // the number of the pushbutton pin
const int ledPin = 13;        // The number of the LED pin
int buttonState;              // the current reading from the input pin
int lastButtonState = LOW;    // the previous reading from the input pin
int ledCount = 3;             // The default setting is standby
int lastLEDCount = 1;
int theButtonValue;
int TxCount;                  // This is used to limit the number of transmissions
int TxButtonState;            // This is used to limit the number of transmissions
const int TxAttempts = 10;    // This is the number of times the transmitter will send after each button press

//for feather32u4
// Singleton instance of the radio driver
const int RFM95_CS = 8;   // This pin is used by the radio transceiver
const int RFM95_RST = 4;  // This pin is used by the radio transceiver
const int RFM95_INT = 7;  // This pin is used by the radio transceiver

// This is for the Millis delay
unsigned long previousMillis = 0;
const long interval = 1000;


// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x3F for a 16 chars and 2 line display
RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);
  pinMode(ledPin, OUTPUT);

  lcd.init();
  lcd.clear();
  lcd.backlight();      // Make sure backlight is on
  Serial.begin(9600);
  //  while (!Serial) {
  //    delay(1);
  //  }

  delay(100);

  Serial.println("Feather LoRa TX Test!");

  // manual reset
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  while (!rf95.init()) {
    Serial.println("LoRa radio init failed");
    Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
    while (1);
  }
  Serial.println("LoRa radio init OK!");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
  // you can set transmitter powers from 5 to 23 dBm:
  rf95.setTxPower(23, false);
}

int16_t packetnum = 0;  // packet counter, we increment per xmission

void loop()
{
  readTheButton(ledCount);

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    int radiopacket = 0;

    radiopacket = ledCount;

    lcdDisplay(radiopacket);

    TxButtonState = digitalRead(buttonPin);
    //  digitalRead(buttonPin);
    if (TxButtonState == HIGH) {
      TxCount = 0;
    }
    if (TxCount < TxAttempts) {
      Serial.print("The TX Count is ");
      Serial.println(TxCount);
      itoa(packetnum++, radiopacket, radiopacket);
   
      Serial.print("Sending "); Serial.println(radiopacket);

      Serial.println("Sending...");
      digitalWrite(ledPin, HIGH);
      delay(10);
      rf95.send((uint8_t *)&radiopacket, sizeof(radiopacket));

      Serial.println("Waiting for packet to complete...");
      delay(10);
      rf95.waitPacketSent();


      // Now wait for a reply
      uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
      uint8_t len = sizeof(buf);

      Serial.println("Waiting for reply...");
      if (rf95.waitAvailableTimeout(1000))
      {
        // Should be a reply message for us now
        if (rf95.recv(buf, &len))
        {
          Serial.print("Got reply: ");
          Serial.println((char*)buf);
          Serial.print("RSSI: ");
          Serial.println(rf95.lastRssi(), DEC);
        }
        else
        {
          Serial.println("Receive failed");
        }
      }
      else
      {
        Serial.println("No reply, is there a listener around?");
      }
      digitalWrite(ledPin, LOW);
      TxCount++;
    }

  }
}
void lcdDisplay(int radiopacket) {

  if (lastPacket != radiopacket) {
    lcd.clear(); // clear the display
  }
  lcd.setCursor(0, 0); // Character Position 0, Line 1
  lcd.print("Radio Packet = ");
  lcd.setCursor(15, 0);// Character Position 15, Line 1
  lcd.print(radiopacket);
  if (radiopacket == 1) {
    lcd.setCursor(0, 1);// Character Position 0, Line 2
    lcd.print("A Day");
  }
  if (radiopacket == 2) {
    lcd.setCursor(0, 1);// Character Position 0, Line 2
    lcd.print("B Day");
  }
  if (radiopacket == 3) {
    lcd.setCursor(0, 1);// Character Position 0, Line 2
    lcd.print("Standby");
  }
  lastPacket = radiopacket;

}

void readTheButton (int theButtonValue) {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only increment the LED count if the new button state is HIGH
      if (buttonState == HIGH) {
        ledCount++;
        if (ledCount > 3) {
          ledCount = 1;
        }

      }
    }
  }

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
  return ledCount;
}

Logged

AF7JA

  • Member
  • Posts: 302
Re: RadioFruit Arduino boards Legality Thoughts and Questions
« Reply #14 on: March 08, 2023, 05:53:06 PM »

And here is the receiver code. It includes some functions that define the images. The way it is written, it will be easy to add more images (Like MAPP test day, State Test day, KELPA test day, NAEP test day. . . you get the picture. . .)
Quote
http://#include <FastLED.h>
#include <SPI.h>
#include <RH_RF95.h>

#define RF95_FREQ 915.0 // Change to 434.0 or other frequency, must match RX's freq!
#define LED 13  // Builtin LED
#define LED_PIN     11 //this pin connects to the panel
#define NUM_LEDS    256
//for feather32u4
//#define RFM95_CS 8
//#define RFM95_RST 4
//#define RFM95_INT 7

int inPin1 = 2;   // from the rotary switch
int val1 = 0;
int inPin2 = 3;   // from the rotary switch
int val2 = 0;
int inPin3 = 5;   // from the rotary switch
int val3 = 0;
int previousVal;
int RxValue;

CRGB leds[NUM_LEDS];
//#define LED1 11
//#define LED2 12

const int RFM95_CS = 8;   // this is added by me
const int RFM95_RST = 4;  // this is added by me
const int RFM95_INT = 7;  // this is added by me

RH_RF95 rf95(RFM95_CS, RFM95_INT);

#define LED 13  // Blinky on receipt

void setup() {

  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(25);
  FastLED.clear();

  pinMode(LED, OUTPUT);
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

  Serial.begin(9600);

  delay(100);

  Serial.println("Feather LoRa RX Test!");

  // manual reset
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  while (!rf95.init()) {
    Serial.println("LoRa radio init failed");
    Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
    while (1);
  }
  Serial.println("LoRa radio init OK!");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
  // you can set transmitter powers from 5 to 23 dBm:
  rf95.setTxPower(23, false);

}

void loop() {
  int buf = 0;
  int RxReceive;
  if (rf95.available())
  {

    uint8_t buf = 200;
    uint8_t len = sizeof(buf);

    if (rf95.recv((uint8_t*)&buf, &len))
    {
      digitalWrite(LED, HIGH);
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      //     Serial.println((char*)buf);
      Serial.println(buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);

      RxReceive = buf;
      // Send a reply
      uint8_t data[] = "AF7JA says hello back to you";
      rf95.send(data, sizeof(data));
      rf95.waitPacketSent();
      Serial.println("Sent a reply");
      digitalWrite(LED, LOW);
    }
    else
    {
      Serial.println("Receive failed");
    }

  }





  int readPot = analogRead(A1); // This is where the 10K Poteometer is connected
  int brightness = map(readPot, 0, 1023, 1, 200); // Maping the 0-1023 value from the pot to 1-200, we use 200 because 200-226 had no real impact
  FastLED.setBrightness(brightness); // here we change the brightness of the LED array
  //  if (val1 == HIGH) {       // switch position 1
  Serial.print("at the if, buf = ");
  Serial.println(RxReceive);
  if (RxReceive == 1) {

    if (previousVal != 1) { // checks to see if the display is set to another letter
      FastLED.clear();      // if the screen was set to a different letter, it clears the screen
    }
    else
      wordDay();    // prints "day"
    letterA();    // prints "A"


    previousVal = 1;
  }
  else if (RxReceive == 2) {
    // else if (val2 == HIGH) {  // switch position 2
    if (previousVal != 2) { // checks to see if the display is set to another letter
      FastLED.clear();      // if the screen was set to a different letter, it clears the screen
    }
    else
      wordDay();   // prints "day"
    letterB();    // prints "B"

    previousVal = 2;
  }
  else if (RxReceive == 48||3||-48) {
    FastLED.clear();
    leds[1] = CRGB(50, 50, 50);
    FastLED.show();
    previousVal = 48;
  }

}
void wordDay() {
  // Spells "DAY"
  leds[2] = CRGB(0, 255, 150);
  FastLED.show();
  leds[3] = CRGB(255, 0, 0);
  FastLED.show();
  leds[30] = CRGB(0, 255, 0);
  FastLED.show();
  leds[28] = CRGB(0, 0, 255);
  FastLED.show();
  leds[33] = CRGB(150, 0, 255);
  FastLED.show();
  leds[35] = CRGB(255, 200, 20);
  FastLED.show();
  leds[62] = CRGB(85, 60, 180);
  FastLED.show();
  leds[60] = CRGB(50, 255, 20);
  FastLED.show();
  leds[66] = CRGB(50, 255, 20);
  FastLED.show();
  leds[67] = CRGB(255, 0, 0);
  FastLED.show();
  leds[98] = CRGB(0, 255, 0);
  FastLED.show();
  leds[124] = CRGB(0, 0, 255);
  FastLED.show();
  leds[126] = CRGB(150, 0, 255);
  FastLED.show();
  leds[131] = CRGB(255, 200, 20);
  FastLED.show();
  leds[130] = CRGB(85, 60, 180);
  FastLED.show();
  leds[129] = CRGB(50, 255, 20);
  FastLED.show();
  leds[156] = CRGB(50, 255, 20);
  FastLED.show();
  leds[158] = CRGB(255, 0, 0);
  FastLED.show();
  leds[188] = CRGB(255, 0, 0);
  FastLED.show();
  leds[190] = CRGB(0, 255, 0);
  FastLED.show();
  leds[195] = CRGB(0, 0, 255);
  FastLED.show();
  leds[193] = CRGB(150, 0, 255);
  FastLED.show();
  leds[221] = CRGB(255, 200, 20);
  FastLED.show();
  leds[226] = CRGB(85, 60, 180);
  FastLED.show();
  leds[253] = CRGB(50, 255, 20);
  FastLED.show();
}
void letterA() {
  // Letter"A"

  leds[10] = CRGB(50, 255, 20);
  FastLED.show();
  leds[20] = CRGB(255, 0, 0);
  FastLED.show();
  leds[21] = CRGB(0, 255, 0);
  FastLED.show();
  leds[22] = CRGB(0, 0, 255);
  FastLED.show();
  leds[40] = CRGB(150, 0, 255);
  FastLED.show();
  leds[41] = CRGB(255, 200, 20);
  FastLED.show();
  leds[43] = CRGB(85, 60, 180);
  FastLED.show();
  leds[44] = CRGB(50, 255, 20);
  FastLED.show();
  leds[55] = CRGB(50, 255, 20);
  FastLED.show();
  leds[54] = CRGB(255, 0, 0);
  FastLED.show();
  leds[52] = CRGB(255, 0, 0);
  FastLED.show();
  leds[51] = CRGB(0, 255, 0);
  FastLED.show();
  leds[71] = CRGB(0, 0, 255);
  FastLED.show();
  leds[72] = CRGB(150, 0, 255);
  FastLED.show();
  leds[76] = CRGB(255, 200, 20);
  FastLED.show();
  leds[77] = CRGB(85, 60, 180);
  FastLED.show();
  leds[88] = CRGB(50, 255, 20);
  FastLED.show();
  leds[87] = CRGB(50, 255, 20);
  FastLED.show();
  leds[83] = CRGB(255, 0, 0);
  FastLED.show();
  leds[82] = CRGB(0, 255, 0);
  FastLED.show();
  leds[102] = CRGB(0, 0, 255);
  FastLED.show();
  leds[103] = CRGB(150, 0, 255);
  FastLED.show();
  leds[109] = CRGB(255, 200, 20);
  FastLED.show();
  leds[110] = CRGB(85, 60, 180);
  FastLED.show();
  leds[121] = CRGB(50, 255, 20);
  FastLED.show();
  leds[120] = CRGB(50, 255, 20);
  FastLED.show();
  leds[114] = CRGB(255, 0, 0);
  FastLED.show();
  leds[113] = CRGB(255, 0, 0);
  FastLED.show();
  leds[134] = CRGB(0, 255, 0);
  FastLED.show();
  leds[135] = CRGB(0, 0, 255);
  FastLED.show();
  leds[136] = CRGB(150, 0, 255);
  FastLED.show();
  leds[137] = CRGB(255, 200, 20);
  FastLED.show();
  leds[138] = CRGB(85, 60, 180);
  FastLED.show();
  leds[139] = CRGB(50, 255, 20);
  FastLED.show();
  leds[140] = CRGB(255, 0, 0);
  FastLED.show();
  leds[141] = CRGB(0, 255, 0);
  FastLED.show();
  leds[142] = CRGB(0, 0, 255);
  FastLED.show();
  leds[145] = CRGB(150, 0, 255);
  FastLED.show();
  leds[146] = CRGB(255, 200, 20);
  FastLED.show();
  leds[147] = CRGB(85, 60, 180);
  FastLED.show();
  leds[148] = CRGB(50, 255, 20);
  FastLED.show();
  leds[149] = CRGB(50, 255, 20);
  FastLED.show();
  leds[150] = CRGB(255, 0, 0);
  FastLED.show();
  leds[151] = CRGB(255, 0, 0);
  FastLED.show();
  leds[152] = CRGB(0, 255, 0);
  FastLED.show();
  leds[153] = CRGB(0, 0, 255);
  FastLED.show();
  leds[166] = CRGB(150, 0, 255);
  FastLED.show();
  leds[167] = CRGB(255, 200, 20);
  FastLED.show();
  leds[173] = CRGB(85, 60, 180);
  FastLED.show();
  leds[174] = CRGB(50, 255, 20);
  FastLED.show();
  leds[177] = CRGB(50, 255, 20);
  FastLED.show();
  leds[178] = CRGB(255, 0, 0);
  FastLED.show();
  leds[184] = CRGB(0, 255, 0);
  FastLED.show();
  leds[185] = CRGB(0, 0, 255);
  FastLED.show();
  leds[198] = CRGB(150, 0, 255);
  FastLED.show();
  leds[199] = CRGB(255, 200, 20);
  FastLED.show();
  leds[205] = CRGB(85, 60, 180);
  FastLED.show();
  leds[206] = CRGB(50, 255, 20);
  FastLED.show();
  leds[209] = CRGB(50, 255, 20);
  FastLED.show();
  leds[210] = CRGB(255, 0, 0);
  FastLED.show();
  leds[216] = CRGB(255, 0, 0);
  FastLED.show();
  leds[217] = CRGB(0, 255, 0);
  FastLED.show();
  leds[229] = CRGB(0, 0, 255);
  FastLED.show();
  leds[230] = CRGB(150, 0, 255);
  FastLED.show();
  leds[231] = CRGB(255, 200, 20);
  FastLED.show();
  leds[237] = CRGB(85, 60, 180);
  FastLED.show();
  leds[238] = CRGB(50, 255, 20);
  FastLED.show();
  leds[239] = CRGB(0, 255, 0);
  FastLED.show();
  leds[240] = CRGB(0, 0, 255);
  FastLED.show();
  leds[241] = CRGB(150, 0, 255);
  FastLED.show();
  leds[242] = CRGB(255, 200, 20);
  FastLED.show();
  leds[248] = CRGB(85, 60, 180);
  FastLED.show();
  leds[249] = CRGB(50, 255, 20);
  FastLED.show();
  leds[250] = CRGB(50, 255, 20);
  FastLED.show();
}
void letterB() {
  // Letter"B"
  leds[11] = CRGB(50, 255, 20);
  FastLED.show();
  leds[12] = CRGB(255, 0, 0);
  FastLED.show();
  leds[13] = CRGB(0, 0, 255);
  FastLED.show();
  leds[14] = CRGB(150, 0, 255);
  FastLED.show();
  leds[17] = CRGB(255, 200, 20);
  FastLED.show();
  leds[18] = CRGB(85, 60, 180);
  FastLED.show();
  leds[19] = CRGB(50, 255, 20);
  FastLED.show();
  leds[20] = CRGB(50, 255, 20);
  FastLED.show();
  leds[21] = CRGB(255, 0, 0);
  FastLED.show();
  leds[41] = CRGB(255, 0, 0);
  FastLED.show();
  leds[42] = CRGB(0, 255, 0);
  FastLED.show();
  leds[45] = CRGB(0, 0, 255);
  FastLED.show();
  leds[46] = CRGB(150, 0, 255);
  FastLED.show();
  leds[49] = CRGB(255, 200, 20);
  FastLED.show();
  leds[50] = CRGB(85, 60, 180);
  FastLED.show();
  leds[54] = CRGB(50, 255, 20);
  FastLED.show();
  leds[73] = CRGB(50, 255, 20);
  FastLED.show();
  leds[77] = CRGB(255, 0, 0);
  FastLED.show();
  leds[78] = CRGB(0, 255, 0);
  FastLED.show();
  leds[81] = CRGB(0, 0, 255);
  FastLED.show();
  leds[82] = CRGB(150, 0, 255);
  FastLED.show();
  leds[86] = CRGB(255, 200, 20);
  FastLED.show();
  leds[110] = CRGB(85, 60, 180);
  FastLED.show();
  leds[109] = CRGB(50, 255, 20);
  FastLED.show();
  leds[106] = CRGB(50, 255, 20);
  FastLED.show();
  leds[105] = CRGB(255, 0, 0);
  FastLED.show();
  leds[113] = CRGB(255, 0, 0);
  FastLED.show();
  leds[114] = CRGB(0, 255, 0);
  FastLED.show();
  leds[115] = CRGB(0, 0, 255);
  FastLED.show();
  leds[116] = CRGB(150, 0, 255);
  FastLED.show();
  leds[117] = CRGB(255, 200, 20);
  FastLED.show();
  leds[138] = CRGB(85, 60, 180);
  FastLED.show();
  leds[139] = CRGB(50, 255, 20);
  FastLED.show();
  leds[140] = CRGB(255, 0, 0);
  FastLED.show();
  leds[141] = CRGB(0, 255, 0);
  FastLED.show();
  leds[142] = CRGB(0, 0, 255);
  FastLED.show();
  leds[145] = CRGB(150, 0, 255);
  FastLED.show();
  leds[146] = CRGB(255, 200, 20);
  FastLED.show();
  leds[149] = CRGB(85, 60, 180);
  FastLED.show();
  leds[150] = CRGB(50, 255, 20);
  FastLED.show();
  leds[169] = CRGB(50, 255, 20);
  FastLED.show();
  leds[173] = CRGB(255, 0, 0);
  FastLED.show();
  leds[174] = CRGB(255, 0, 0);
  FastLED.show();
  leds[177] = CRGB(0, 255, 0);
  FastLED.show();
  leds[178] = CRGB(0, 0, 255);
  FastLED.show();
  leds[182] = CRGB(150, 0, 255);
  FastLED.show();
  leds[201] = CRGB(255, 200, 20);
  FastLED.show();
  leds[205] = CRGB(85, 60, 180);
  FastLED.show();
  leds[206] = CRGB(50, 255, 20);
  FastLED.show();
  leds[209] = CRGB(50, 255, 20);
  FastLED.show();
  leds[210] = CRGB(255, 0, 0);
  FastLED.show();
  leds[213] = CRGB(0, 255, 0);
  FastLED.show();
  leds[214] = CRGB(0, 0, 255);
  FastLED.show();
  leds[234] = CRGB(150, 0, 255);
  FastLED.show();
  leds[235] = CRGB(255, 200, 20);
  FastLED.show();
  leds[236] = CRGB(85, 60, 180);
  FastLED.show();
  leds[237] = CRGB(50, 255, 20);
  FastLED.show();
  leds[238] = CRGB(50, 255, 20);
  FastLED.show();
  leds[241] = CRGB(255, 0, 0);
  FastLED.show();
  leds[242] = CRGB(255, 0, 0);
  FastLED.show();
  leds[243] = CRGB(0, 255, 0);
  FastLED.show();
  leds[244] = CRGB(0, 0, 255);
  FastLED.show();
  leds[40] = CRGB(0, 255, 0);
  FastLED.show();
  leds[55] = CRGB(0, 0, 255);
  FastLED.show();
  leds[72] = CRGB(150, 0, 255);
  FastLED.show();
  leds[87] = CRGB(255, 200, 20);
  FastLED.show();
  leds[104] = CRGB(85, 60, 180);
  FastLED.show();
  leds[151] = CRGB(50, 255, 20);
  FastLED.show();
  leds[168] = CRGB(50, 255, 20);
  FastLED.show();
  leds[183] = CRGB(255, 0, 0);
  FastLED.show();
  leds[200] = CRGB(255, 0, 0);
  FastLED.show();
  leds[215] = CRGB(0, 255, 0);
  FastLED.show();
  leds[22] = CRGB(150, 0, 255);
  FastLED.show();
  leds[233] = CRGB(255, 200, 20);
  FastLED.show();
}
void wordTest() {
  // spells "test"
  leds[0] = CRGB(50, 255, 20);
  FastLED.show();
  leds[1] = CRGB(255, 0, 0);
  FastLED.show();
  leds[2] = CRGB(0, 0, 255);
  FastLED.show();
  leds[30] = CRGB(150, 0, 255);
  FastLED.show();
  leds[33] = CRGB(255, 200, 20);
  FastLED.show();
  leds[62] = CRGB(85, 60, 180);
  FastLED.show();
  leds[64] = CRGB(50, 255, 20);
  FastLED.show();
  leds[65] = CRGB(50, 255, 20);
  FastLED.show();
  leds[66] = CRGB(255, 0, 0);
  FastLED.show();
  leds[93] = CRGB(255, 0, 0);
  FastLED.show();
  leds[97] = CRGB(0, 255, 0);
  FastLED.show();
  leds[98] = CRGB(0, 0, 255);
  FastLED.show();
  leds[125] = CRGB(150, 0, 255);
  FastLED.show();
  leds[128] = CRGB(255, 200, 20);
  FastLED.show();
  leds[129] = CRGB(85, 60, 180);
  FastLED.show();
  leds[130] = CRGB(50, 255, 20);
  FastLED.show();
  leds[157] = CRGB(50, 255, 20);
  FastLED.show();
  leds[160] = CRGB(255, 0, 0);
  FastLED.show();
  leds[161] = CRGB(0, 255, 0);
  FastLED.show();
  leds[162] = CRGB(0, 0, 255);
  FastLED.show();
  leds[191] = CRGB(150, 0, 255);
  FastLED.show();
  leds[192] = CRGB(255, 200, 20);
  FastLED.show();
  leds[193] = CRGB(85, 60, 180);
  FastLED.show();
  leds[194] = CRGB(50, 255, 20);
  FastLED.show();
  leds[222] = CRGB(50, 255, 20);
  FastLED.show();
  leds[225] = CRGB(255, 0, 0);
  FastLED.show();
  leds[254] = CRGB(255, 0, 0);
  FastLED.show();
}
void letterM() {
  // Letter"M"
  leds[4] = CRGB(50, 255, 20);
  FastLED.show();
  leds[5] = CRGB(255, 0, 0);
  FastLED.show();
  leds[6] = CRGB(0, 0, 255);
  FastLED.show();
  leds[13] = CRGB(150, 0, 255);
  FastLED.show();
  leds[14] = CRGB(255, 200, 20);
  FastLED.show();
  leds[15] = CRGB(85, 60, 180);
  FastLED.show();
  leds[16] = CRGB(50, 255, 20);
  FastLED.show();
  leds[17] = CRGB(50, 255, 20);
  FastLED.show();
  leds[18] = CRGB(255, 0, 0);
  FastLED.show();
  leds[25] = CRGB(255, 0, 0);
  FastLED.show();
  leds[26] = CRGB(0, 255, 0);
  FastLED.show();
  leds[27] = CRGB(0, 0, 255);
  FastLED.show();
  leds[37] = CRGB(150, 0, 255);
  FastLED.show();
  leds[38] = CRGB(255, 200, 20);
  FastLED.show();
  leds[45] = CRGB(85, 60, 180);
  FastLED.show();
  leds[46] = CRGB(50, 255, 20);
  FastLED.show();
  leds[49] = CRGB(50, 255, 20);
  FastLED.show();
  leds[51] = CRGB(255, 0, 0);
  FastLED.show();
  leds[56] = CRGB(0, 255, 0);
  FastLED.show();
  leds[58] = CRGB(0, 0, 255);
  FastLED.show();
  leds[69] = CRGB(150, 0, 255);
  FastLED.show();
  leds[71] = CRGB(255, 200, 20);
  FastLED.show();
  leds[76] = CRGB(85, 60, 180);
  FastLED.show();
  leds[78] = CRGB(50, 255, 20);
  FastLED.show();
  leds[81] = CRGB(50, 255, 20);
  FastLED.show();
  leds[83] = CRGB(255, 0, 0);
  FastLED.show();
  leds[88] = CRGB(255, 0, 0);
  FastLED.show();
  leds[90] = CRGB(0, 255, 0);
  FastLED.show();
  leds[101] = CRGB(0, 0, 255);
  FastLED.show();
  leds[104] = CRGB(150, 0, 255);
  FastLED.show();
  leds[107] = CRGB(255, 200, 20);
  FastLED.show();
  leds[110] = CRGB(85, 60, 180);
  FastLED.show();
  leds[113] = CRGB(50, 255, 20);
  FastLED.show();
  leds[116] = CRGB(255, 0, 0);
  FastLED.show();
  leds[119] = CRGB(0, 255, 0);
  FastLED.show();
  leds[122] = CRGB(0, 0, 255);
  FastLED.show();
  leds[133] = CRGB(150, 0, 255);
  FastLED.show();
  leds[136] = CRGB(255, 200, 20);
  FastLED.show();
  leds[139] = CRGB(85, 60, 180);
  FastLED.show();
  leds[142] = CRGB(50, 255, 20);
  FastLED.show();
  leds[145] = CRGB(50, 255, 20);
  FastLED.show();
  leds[149] = CRGB(255, 0, 0);
  FastLED.show();
  leds[150] = CRGB(255, 0, 0);
  FastLED.show();
  leds[154] = CRGB(0, 255, 0);
  FastLED.show();
  leds[165] = CRGB(0, 0, 255);
  FastLED.show();
  leds[169] = CRGB(150, 0, 255);
  FastLED.show();
  leds[170] = CRGB(255, 200, 20);
  FastLED.show();
  leds[174] = CRGB(85, 60, 180);
  FastLED.show();
  leds[177] = CRGB(50, 255, 20);
  FastLED.show();
  leds[181] = CRGB(50, 255, 20);
  FastLED.show();
  leds[182] = CRGB(255, 0, 0);
  FastLED.show();
  leds[186] = CRGB(0, 255, 0);
  FastLED.show();
  leds[197] = CRGB(0, 0, 255);
  FastLED.show();
  leds[206] = CRGB(150, 0, 255);
  FastLED.show();
  leds[209] = CRGB(255, 200, 20);
  FastLED.show();
  leds[218] = CRGB(85, 60, 180);
  FastLED.show();
  leds[228] = CRGB(50, 255, 20);
  FastLED.show();
  leds[229] = CRGB(50, 255, 20);
  FastLED.show();
  leds[238] = CRGB(255, 0, 0);
  FastLED.show();
  leds[239] = CRGB(255, 0, 0);
  FastLED.show();
  leds[240] = CRGB(0, 255, 0);
  FastLED.show();
  leds[241] = CRGB(0, 0, 255);
  FastLED.show();
  leds[250] = CRGB(0, 255, 0);
  FastLED.show();
  leds[251] = CRGB(0, 0, 255);
}

void RxRecieve() {
  int buf = 0;
  if (rf95.available())
  {
    // Should be a message for us now
    //    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t buf = 200;
    uint8_t len = sizeof(buf);

    if (rf95.recv((uint8_t*)&buf, &len))
    {
      digitalWrite(LED, HIGH);
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      //     Serial.println((char*)buf);
      Serial.println(buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
      int RxValue = buf;
      // Send a reply
      uint8_t data[] = "AF7JA says hello back to you";
      rf95.send(data, sizeof(data));
      rf95.waitPacketSent();
      Serial.println("Sent a reply");
      digitalWrite(LED, LOW);
    }
    else
    {
      Serial.println("Receive failed");
    }
    return RxValue;
  }

}

When finished this project, and the code, look nothing like the inspiration I drew from the magazine. But, amazingly enough, it seems to work.
« Last Edit: March 08, 2023, 05:58:45 PM by AF7JA »
Logged
Pages: [1]   Go Up