Micro/Leonardo texting with phototransistor

Hi guys,

Trying to use a phototransistor to display some text with a micro/leonardo. Everything is working atm. only the text/character is spamming 3-4 times when I pulse with the phototransistor. Is there a way to fix this?

block; phototransistor needs 0.5 sec light, led goes on, character/text on screen, led off.

int ledPin = 3;
int buttonPin = 2;

int firsttime = 1;
unsigned long startTime;
unsigned long pressTime;

void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
Keyboard.begin();

}

void loop()
{
if(digitalRead(buttonPin) == HIGH)
{
 if(firsttime == 1)
 {
  startTime = millis();
  firsttime=0;
 }
 pressTime = millis()- startTime;
 if(pressTime >= 1){
  
 }
 if(pressTime>500){
  digitalWrite(ledPin, HIGH);
  Keyboard.press('a');                          // Also tested Keyboard.write, etc etc 
  delay(100);
  Keyboard.releaseAll();
 }
}
else if(firsttime == 0){
 firsttime = 1;

 digitalWrite(ledPin, LOW);
}
}
 if(pressTime >= 1){

 }

So, if pressTime is greater than or equal to one milllisecond, do nothing at all. Why?

If you have further questions, a description of your circuit would be nice. A phototransistor can only receive light, but not emit, and it cannot display text on a screen.

@ aar;

This is the only code that seems to do what I want, played around with hold-button and debounce adjust. If I leave that if(pressTime >= 1){ }, the code won’t run as intended.

@ DrDiettrich;

phototransistor needs 0.5 sec light before the led goes on and shows a word or text on a screen via the micro. It acts like a button that needs 0.5 sec press before something happens.

Anyway, still needing some advice on the 3-4 keyboard button spam :frowning:

Your code repeats the conditional code after if(pressTime>=500) with every iteration of loop(), until the button is released.

One solution could be an extension of your state machine, with more state values for firsttime, like 0: button released (wait for press) 1: button pressed, no action taken so far (debouncing) 2: button pressed, action taken (waiting for key release)

You can rename firsttime into e.g. buttonState, to indicate the new usage of the variable, and create constants with meaningful names for the states.

Already tried to use a FSM, but without any succes. The problem is that, when I have to wait for the key release, the character is already spamming 3-4 times.

Can’t find out anything like; shine light for 0.5 on phototransistor, do something, ignore that input, do something.

My bad, sorry :-( I missed another state in between 1 and 2, that terminates the pulse. The updated states then are: 0: button released (wait for press) 1: button pressed, no action taken so far (debouncing) 2: action in progress (for the required time) 3: button pressed, action taken (waiting for key release)

The FSM returns from 1 to 0 when the button is released before the debounce interval. Otherwise it moves from 1 to 2 after the debounce interval, starting the pulse and pulse start time. In state 2 it waits only for the pulse duration to elapse, regardless of the button state. Afterwards it moves to state 0 or 3, depending on the button state.

Keep the state handling separate, i.e. check the state and do only what applies in that current state. When a condition is met for the current state, start the action related to the new state, then update the state variable.

What am I missing on this? Nothing happens when uploaded :grin:

const int buttonPin = 2;     // the number of the phototransistor pin
const int ledPin =  3;      // the number of the LED pin

int buttonState = 0;

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

}
byte pressCount = 1;
void loop() {
  
  switch(pressCount){                              
    case 1:
    if(buttonState == HIGH)
    pressCount = 2;
    break;
    
    case 2:
    delay(500);
    pressCount = 3;
    break;
    
    case 3:
    if(buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
    delay(500);
    pressCount = 1;
    break; }
    
    else if(buttonState == LOW) {
    pressCount = 1;
    break; }
    
  }
    
    
    

}
    if(buttonState == HIGH);

Can you find ONE example of an if statement that ends with a semicolon?

Woeps, missed dat ";" :D Anyway, still not working :drooling_face:

Anyway, still not working

Yes, it is. That it is not doing what you expect is NOT the same thing.

We do NOT know what the code actually does (and the lack of Serial.print() statements strongly suggests that you don't, either).

We do NOT know what you expect it to do.

So, we are not likely to be able to help you.

You forgot state 0, the start state, and you never read the button.

DrDiettrich: You forgot state 0, the start state, and you never read the button.

Something like this ?

case 0:
    if(buttonState == LOW)
    pressCount = 1;

Where do you update buttonState? It's a constant value right now, but it should reflect the button state (pressed/released).

Thanks guys :art: made the mistake to continue working.

Like we say in belgium: You can't see the trees, trough the forrest :D

Anyway; this is working:

const int buttonPin = 2;     // the number of the phototransistor pin
const int ledPin =  3;      // the number of the LED pin

int buttonState = 0;
int lastButtonState = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  Keyboard.begin();
}
byte pressCount = 1;

void loop() {
    buttonState = digitalRead(buttonPin); 
    
    switch(pressCount){     
    case 1:
    if(buttonState != lastButtonState){
      if(buttonState == HIGH){
      pressCount = 2;
      break;}
   
      case 2:
      delay(500);
      pressCount = 3;
      break;
   
      case 3:
      if(buttonState == HIGH) {
      digitalWrite(ledPin, HIGH);
      Keyboard.write('a');
      delay(100);
      digitalWrite(ledPin, LOW);
      pressCount = 1;
      lastButtonState = buttonState;
      break; 
      }      
      
      else if(buttonState == LOW) {
      pressCount = 1;
      lastButtonState = buttonState;
      break; 
      }
   }
   }
   

   
  
  
  
   


}

Anyway; this is working:

I'm surprised, with case statements in if blocks.

Put EVERY { on a line by itself. Put EVERY } on a line BY ITSELF. Use Tools + Auto Format. Decide for yourself if the program structure makes sense.