Does brightness of an LED bulb have to be set in the loop function?

Hello, I am relatively new to using C, so I began to experiment with the standard Arduino UNO microcontroller board to see if I could emit light through an LED bulb in a sequence of durations. I am attempting to create a simple Morse code translator, so the shorter durations of light would represent the dots in Morse, while the longer durations would represent the dashes.

My problem: I am having trouble actually emitting any light at all. I am certain that I have the pins in the correct orientation, as it was just working previously when I ran a simple LED fade-in/fade-out sketch. I am using the same components in this sketch (a connecting wire, a resistor, and an LED bulb).

I am wondering why the brightness of the bulb is not affected when I run the sketch. I have a bool which is switched on, and then off after a delay(). I do not think that there is anything wrong with my logic, but if there is I have attached the script below. I have mostly commented the code, but if anything is unclear please notify me. I can’t see anything fundamentally different between this sketch and my fade sketch other than the fact that I am turning the LED on (setting the brightness) in a separate function rather than in the loop() function. Any advice would be appreciated.

Thank you

MorseCodeSketch.ino (3.95 KB)

Attached code:

I’ll comment next.

// Morse code
// turn light on and off at a certain sequence of speeds
// Letters and their corresponding morse code translations are held in a char array
// dots and dashes are represented by a character
// 'S' represents a dot, while 'L' represents a dash
// '/' represents a space
// Iterate through the input sentence char array
// For each letter in the sentence, find that letter in the morse code char array
// Once the letter is found, iterate through the morse code array until you don't find an 'S', 'L', or '/'
// Emit the light accordingly

int ledPin = 10;            // Output pin
float timeInterval = 200;   // Interval between dots and dashes

int maxB = 255;             // Maximum brightness of LED
int fadeAmount = maxB/5;    // Amount to increase/decrease brightness during a dot/dash
int minB = 0;               // Minimum brightness of LED
int brightness = minB;      // Brightness starts at 0
bool on = false;            // Toggles the led on and off

char morseLetters[] = { ' ', '/',
'a', 'S', 'L',
'b', 'L', 'S', 'S', 'S',
'c', 'L', 'S', 'L', 'S',
'd', 'L', 'S', 'S',
'e', 'S',
'f', 'S', 'S', 'L', 'S',
'g', 'L', 'L', 'S',
'h', 'S', 'S', 'S', 'S',
'i', 'S', 'S',
'j', 'S', 'L', 'L', 'L',
'k', 'L', 'S', 'L',
'l', 'S', 'L', 'S', 'S',
'm', 'L', 'L',
'n', 'L', 'S',
'o', 'L', 'L', 'L',
'p', 'S', 'L', 'L', 'S',
'q', 'L', 'L', 'S', 'L',
'r', 'S', 'L', 'S',
's', 'S', 'S','S',
't', 'L',
'u', 'S', 'S', 'L',
'v', 'S', 'S', 'S', 'L',
'w', 'S', 'L', 'L',
'x', 'L', 'S', 'S', 'L',
'y', 'L', 'S', 'L', 'L',
'z', 'L', 'L', 'S', 'S'};             // Following each letter is the corresponding morse code translation in dots and dashes ('S' and 'L')

int morseLen = strlen(morseLetters);  // Length of morse code char array

char sentence[] = "hello";            // Input sentence to translate

int sentenceLen = strlen(sentence);   // Number of characters in input sentence

void setup() {
  
  Serial.begin(9600);       // Initialize serial comms at 9600 baud
  pinMode(ledPin, OUTPUT);  // set pinMode of outputPin to OUTPUT
}

void loop() {
  
  analogWrite(ledPin, brightness);    // Set brightness of LED bulb to brightness variable

  Translate(sentence);
  Serial.println(on);
  //light logic
  if(on)
  {
    Serial.println(brightness);
    // increase brightness up to maximum brightness while it's on
    if(brightness < maxB)
    {
      Serial.println(brightness);
      brightness += fadeAmount;
    }
  }
  else
  {
    Serial.println(brightness);
    // decrease brightness down to minimum brightness while it's off
    if(brightness > minB)
    {
      Serial.println(brightness);
      brightness -= fadeAmount;
    }
  }
}

// Iterate through letters in sentence
// Find the letter in morse code array
// Change brightness of LED according to the subsequential dots and dashes
// Continue onto the next letter when an 'S', 'L', or '/' is not found
void Translate(char sentence[])
{
  bool letterFound;
  int letterIndex = 0;
  
//  Serial.println(sentenceLen);
//  Serial.println(morseLen);

  for(int i = 0; i < sentenceLen; i++)
  {
    letterFound = false;
    for(int j = 0; j < morseLen; j++)
    {
      // Found the current letter in the morse code array
      if(sentence[i] == morseLetters[j])
      {
        letterFound = true;             
//        Serial.println(letterFound);
        letterIndex = j;
//        Serial.println(letterIndex);
      }
    }
    if(letterFound)
    {
      for(int s = letterIndex + 1; morseLetters[s] == 'S' || morseLetters[s] == 'L' || morseLetters[s] == '/'; s++)
      {
        EmitAtSpeed(morseLetters[s]);
      }
    }
  }
  
}

// Turn LED on/off at certain speed
// Speed depends on the input character
void EmitAtSpeed(char speed)
{
  Serial.println(speed);
  //
  delay(timeInterval);
  on = true;
  switch(speed)
  {
    case 'S':{
      delay(timeInterval);
      break;
    }
    case 'L':{
      delay(timeInterval * 3);
      break;
    }
    case'/':{
      delay(timeInterval);
      break;
    }
    default:{
      break;
    }
  }
  on = false;

}

You have some issues with the structure. Let's look at what your code does on a typical pass.

So you start by calling analogWrite with your brightness level. It started out at 0. Then you call Translate, it finds the first letter in the sentence and calls EmitAtSpeed. That function is interesting. It sets on to true and then waits for a period of time before setting on right back to false and then exiting. This whole process gets repeated for each letter in the sentence. Finally after the last letter Translate ends and we get back to the loop. Now loop checks the boolean on. It is going to be false because it was always set back to false at the end of EmitAtSpeed and that's the only function that messed with it. Since it is always going to be false here we compare brightness to minB and they're both 0 so we do nothing. At no point have we told any leds to light up. We've only ever had a brightness of 0. That code checking for on isn't running at the same time the code that turns it on and waits a while is.

There are more than enough examples and great tutorials on morse code encoders and decoders out there that I'm not going to create another one here just for you. Go and study. The best ones will use non-blocking techniques meaning there will be no for or while loops and no delay calls in them anywhere.

I see, thank you for the clarification! I will go study some other examples :slight_smile:

So if I simply move the brightness-adjustment code into the EmitAtSpeed function (increase brightness before delay, decrease brightness after), the LED bulb should light up? This is what I attempted to do before, but it produced the same result. In this case, the boolean on wouldn't be necessary, I would be hard-coding brightness to equal 255 or 0.

kirmanator:
I would be hard-coding brightness to equal 255 or 0.

Otherwise known as digitalWrite.