A little help on 'else if' and error spotting please

Having a little trouble and I was wondering if someone could quickly check this over as I'm getting

"a function-definition is not allowed here before '{' token"

error and i can't for the life of me spot the issue.

I'm simply trying to get the code to run 1 instruction set if there's serial data received and one set if it isn't so please do me a favour and point out where I'm wrong in ley man's terms so I can get this working. It's quite irritating because I know this is isn't a complicated issue and don't like wasting anyone's time.

Anyway, here's where I'm at:

#include "FastLED.h"
#define NUM_LEDS 256
#define DATA_PIN 9
#define BRIGHTNESS  150
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100
CRGBPalette16 currentPalette;
TBlendType    currentBlending;

void setup() {
  Serial.begin(500000);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}
int serialnerd () {
  while (!Serial.available()) {}
  return Serial.read();

  currentPalette = ForestColors_p;
  currentBlending = LINEARBLEND;
}

void loop()
{
  if (Serial.available() > 0) {
    goto jinx;
  }
  else if (Serial.available() <= -1) {
    goto eeprom;
  }
  
  void jinx();
  while (serialJinx () != 1) {}
    for (int i = 0; i < NUM_LEDS; i++)
    {
      leds[i].r = serialJinx ();
      leds[i].g = serialJinx ();
      leds[i].b = serialJinx ();
    }
    
  void eeprom() {
    ChangePalettePeriodically();
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1;
    FillLEDsFromPaletteColors( startIndex);
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
  }
  void FillLEDsFromPaletteColors(uint8_t colorIndex) {
    uint8_t brightness = 255;
    for ( int i = 0; i < NUM_LEDS; i++) {
      leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
      colorIndex += 3;
    }
  }
  void ChangePalettePeriodically(
  {
    uint8_t secondHand = (millis() / 1000) % 60;
    static uint8_t lastSecond = 99;

    if ( lastSecond != secondHand) { lastSecond = secondHand;
      if ( secondHand ==  0)  { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND;}
      if ( secondHand == 15)  { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND;}
      if ( secondHand == 45)  { currentPalette = PartyColors_p; currentBlending = LINEARBLEND;}
    }
  }

Tip for the next time, post the WHOLE error. It holds more info then you extracted from it...

But looking at your code it should be pretty obvious. The indentation is even pretty good so you can see directly you try to define functions inside a function (namely in loop()). You can't do that.

Also, NEVER user goto. But as it seems you just try to call the function jinx / eeprom. You do so by

jinx();

And some questions:

  • Why only call eeprom() if serial <= -1?
  • What has the eeprom() function to do with eeprom????
  • Where is serialJinx() supposed to be defined?
int serialnerd () {
  while (!Serial.available()) {}
  return Serial.read();

  currentPalette = ForestColors_p;
  currentBlending = LINEARBLEND;
}

No point in putting code after an unconditional return.

if (Serial.available() <= -1) Doesn't seem very likely, does it?

Thanks for the replies, as far as I understood if no data is received on the port it reads as -1 but I may have misread it. I also added in the < in case I was wrong.

With the eeprom naming I've just called it that because those functions and palettes are being stored directly on the board, just my own way of naming things nothing more.

When I try to call 'jinx();' I get an undeclared in this scope' error so probably syntax somewhere

and:

  • Why only call eeprom() if serial <= -1? - to only run when no serial input is received
  • What has the eeprom() function to do with eeprom???? - none now, it's just how I named things
  • Where is serialJinx() supposed to be defined? - I thought the below was fine for it?
int serialJinx () {
  while (!Serial.available()) {}
  return Serial.read();
  
}

void loop()
{
  if (Serial.available() > 0) {
    jinx();
  }
  else if (Serial.available() = -1) {
    eeprom();
  }
  
  void jinx();
  while (serialJinx () != 1) {}
    for (int i = 0; i < NUM_LEDS; i++)
    {
      leds[i].r = serialJinx ();
      leds[i].g = serialJinx ();
      leds[i].b = serialJinx ();
    }

I'm not sure about this though "The indentation is even pretty good so you can see directly you try to define functions inside a function (namely in loop()). You can't do that."

Anyways, adjusted it to this bar the directly above quoted bit I'm not overly sure on:

#include "FastLED.h"
#define NUM_LEDS 256
#define DATA_PIN 9
#define BRIGHTNESS  150
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100
CRGBPalette16 currentPalette;
TBlendType    currentBlending;

void setup() {
  currentPalette = ForestColors_p;
  currentBlending = LINEARBLEND; 
  Serial.begin(500000);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}
int serialJinx () {
  while (!Serial.available()) {}
  return Serial.read();
  
}

void loop()
{
  if (Serial.available() > 0) {
    jinx();
  }
  else if (Serial.available() = -1) {
    eeprom();
  }
  
void jinx();
  while (serialJinx () != 1) {}
    for (int i = 0; i < NUM_LEDS; i++)
    {
      leds[i].r = serialJinx ();
      leds[i].g = serialJinx ();
      leds[i].b = serialJinx ();
    }
    
void eeprom() {
    ChangePalettePeriodically();
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1;
    FillLEDsFromPaletteColors( startIndex);
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
  }
  void FillLEDsFromPaletteColors(uint8_t colorIndex) {
    uint8_t brightness = 255;
    for ( int i = 0; i < NUM_LEDS; i++) {
      leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
      colorIndex += 3;
    }
  }
  void ChangePalettePeriodically(
  {
    uint8_t secondHand = (millis() / 1000) % 60;
    static uint8_t lastSecond = 99;

    if ( lastSecond != secondHand) { lastSecond = secondHand;
      if ( secondHand ==  0)  { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND;}
      if ( secondHand == 15)  { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND;}
      if ( secondHand == 45)  { currentPalette = PartyColors_p; currentBlending = LINEARBLEND;}
    }

Serial.available returns the number of characters in the receive buffer.

This number is never less than zero.

It looks like you've got functions defined inside other functions. Don't try that, it won't work.

AWOL- I've changed to it to some test values for now, I can can tweak that later to see what's best but I did really think that if no data was received it reads as a -1 but hey ho.

Can you point out the functions inside functions for me so I can get my head around it- I'm new to this and last time I did programming or coding was on a Sinclair Spectrum back in 1981 or 2.

I believe you're confusing Serial.available and Serial.read.

void loop()
{
  if (Serial.available() > 0) {
    jinx();
  }
  else if (Serial.available() = -1) {
    eeprom();
  }
  
void jinx();

Here, the "void jinx();" serves no purpose; it's a function prototype, which the Arduino IDE provides already. You're not calling the function merely introducing it.

Here is a small portion of your code after Auto Formatting it in the IDE

  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i].r = serialJinx ();
    leds[i].g = serialJinx ();
    leds[i].b = serialJinx ();
  }
  void eeprom()
  {
    ChangePalettePeriodically();
    static uint8_t startIndex = 0;

Note that the eeprom() function (terrible name by the way) does not start on the left margin which it should after the Auto Format. This is a sure sign of mismatched { and } somewhere.

Where does the loop() function end, for instance ?

While we are here what is this all about ?

    goto eeprom;

Ah, I think I get you now- think I'll have better results using that? I was going to set the first to around 5 and 2nd as 0 that should give parity between the 2 but I'll have to go and double check what everything is with serial.read again.

AWOL - And with this 'Here, the "void jinx();" serves no purpose; it's a function prototype, which the Arduino IDE provides already'...I've absolutely no idea what you're talking about mate. As far as I understand it each 'void' is basically an instruction set. You have to obviously specify that set which is why it's under void jinx();. If you provide an actual example of what things are supposed to be I'll probably learn.

How about you simply tell me what the actual solution would be using correct syntax? That way I can compare the 2, learn from it, get things right in my head and not replicate the error again. Otherwise I'm simply shaking my head at the screen wondering why you haven't actually shown me a way round this- just thrown more terms at me that you know for a fact I'm not sure on. It's like a Linux forum in here.

void jinx(); //prototype, tells the compiler you will somewhere define a function jinx with no parameters.
//does NOT call it

void jinx(){
  //something something
}
//declares and defines a function jinx without parameters which you can call
//does NOT call it

jinx(); //calls the function jinx which you should have defined elsewhere.

How about you simply tell me what the actual solution would be using correct syntax?

You want to be given a fish rather than being shown how to fish.

If we simply post the corrected code then what are you going to do the next time an error occurs ?

As to the problem, here is a big clue
The code block for every function must start with { and end with } and every { must have a corresponding }

Click to the right of a { and the IDE will put a box round the corresponding } if there is one

Cheers Septillion- made more sense. So got rid of the errors, kind of working in that it runs eeprom when there's no serial input but doesn't seem to be triggering the jinx element so jinx will communicate so there must something wrong somewhere, might try changing serial.read to available in the jinx argument:

#include "FastLED.h"
#define NUM_LEDS 256
#define DATA_PIN 9
#define BRIGHTNESS  150
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100
CRGBPalette16 currentPalette;
TBlendType    currentBlending;

void setup() {
  currentPalette = ForestColors_p;
  currentBlending = LINEARBLEND;
  Serial.begin(500000);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{
  if (Serial.read() >= 0) {
    jinx();
  }
  else if (Serial.read() == -1) {
    eeprom();
  }
}
  int serialJinx () {
  while (!Serial.available()) {}
  return Serial.read();
}
void jinx(){
  while (serialJinx () != 1) {}
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i].r = serialJinx ();
    leds[i].g = serialJinx ();
    leds[i].b = serialJinx ();
  }
}
  void eeprom(){
    uint8_t brightness = 255;
    for ( int i = 0; i < NUM_LEDS; i++) {
      leds[i] = ColorFromPalette( currentPalette, brightness, currentBlending);
    }
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
  }

I'm just going to politely ignore the teach a man to fish context - no point in trying to fish without a rod is there? Nor is there any point in trying that argument without knowing an experience level as a context or it simply flat out fails- even mentioned this but still jargon...people searching for things online come across posts like this and just walk away after reading it realising it's pointless asking for help because you just get baffled even more. Arduino is supposed to be for everyone, a simple little way of doing things- want more people doing things so you get more toys to play with then everyone has to dumb things down COMPLETELY for people. When I've been looking for things in relation to this all I've seen are rude snotty answers to other people and if I'm finding them then everyone else is so how does that make the Arduino community look?

And thanks Septillion for putting it simply but I'm going to look elsewhere for answers, I tried asking here once before and had the same sort of response as well.

I'm just going to politely ignore the teach a man to fish context - no point in trying to fish without a rod is there?

The IDE provides the rod - it is packed with worked examples of C/C++ coding in an Arduino context.

There is no excuse for not playing around with a few of the examples.

Nor is there any point in trying that argument without knowing an experience level as a context or it simply flat out fails-

That argument works both ways - we don't know your experience level, so we pitch answers, and wait for your response, repeat and adjust.