Sketch for diebog

This thread is a sketch for Diebog, as discussed here and in PMs. I am starting a new thread because there has been considerable back-and-forth between myself and diebog over this.

Currently, my specification so far as it goes, in addition to stuff stated on that thread, is:

--wait for beam to break (IDLE)
--beam breaks
--wait 10 seconds (PAUSE_BEFORE_OPEN)
--send signal to ON
--wait half a second (ON_DELAY)
--send signal to OPEN
--wait half a second (OPEN_DELAY)
--release/turn off/float both signals
--wait for beam to reconnect (WAIT_BEAM)
--wait another 2 seconds (PAUSE_BEFORE_CLOSE)
--send ground signal to ON(which deactivates function)
--wait 1/4 of a second (OFF_DELAY)
--turn off ON
--wait for beam to break again (IDLE)

I'll go away, write the sketch, and then post the result on this thread. See y'all in 20 minutes.

Ok.

Diebog, your sketch is at gitub at this link.

If it works for you, please remit $50 AUD to my paypal pmurray@bigpond.com .

If it does not work for you, then don't pay me.

In either case, I am not prepared to do any further work on this sketch for you. If it does not work and you need further help, then do not hesitate to ask for more help either on this thread or elsewhere from someone else. Please do not PM me.

PaulMurrayCbr:
See y'all in 20 minutes.

Why should he pay?- took you 25 :wink:

ardy_guy:
Why should he pay?- took you 25 :wink:

No man - it's taken about a week.

I have now adopted a personal rule - never directly reply to PMs containing questions about programming in a response PM - take it to a forum thread. From now on it's "I have replied to your question in #", or just "ask this question on the original thread, I prefer not to write lengthy replies to questions about programming in PMs".

Thanks Paul! I am very appreciative in all the help you have gave me! So I tried the code out and its allot closer but still not working right. At the end it is supposed to flash the openPin but it flashes the onPin. So I have to figure out how to fix that. Also say if the beam breaks but is reconnected before the 10 second initialization starts, it still goes through the entire sequence. I think maybe adding another if case that if the beam is reconnected before the 10 second countdown is over that it cancels the rest of the program. Basically putting it back in the state of waiting for the beam to break again. Does that make any sense?

Im sorry Paul if I was annoying you thorough PM's. I had asked in my first PM if contacting you via PM was okay and you didn't say it was an issue, so I stuck to PM's as most don't know when a question is posted in a thread unless they subscribe to it. Ive helped other people (on different forums) through PM's as well as the reverse, so I never thought it would be seen as a problem contacting via PM. But again, I am sorry if I was wasting your time or annoying you. I understand you not wishing to have anything further to do with this code and I will never contact you again about it.

I don't mind paying you for your time, 50$ seemed a little steep as I had previously mentioned, but I did agree I would pay you the 50$ for the code. I though that the 50$ covered additional help/modification to the code if further adjustments were needed. But you mentioned you wish not to help or be contacted any further on this code, and if it worked to pay, if it didn't then don't pay. So I am wondering what to do here. The code does technically work (compiles and uploads), but doesn't preform how I need it to work, so further tweaking on the code is required. But then that means I don't pay you for your time you put in this code. You see the conundrum I am in here? I want to be fair to you and me. I don't know how much people usually pay for a code to be written, or what the common consensus on this is. Maybe someone who has had a similar situation could share?

diebog:
I don't know how much people usually pay for a code to be written, or what the common consensus on this is.

I don't have a dog in this fight, but this is something I care about.

As far as "how much people usually pay" there is no such thing. It ranges from nothing to thousands of dollars, depending on what had to be done. You decide if what the programmer wants is worth it to you and either agree to it or not. Paul or I may write code do to the same thing but the cost may be 10x different from one person to the other. It only depends on how much you think the job is worth, just like anything else in life.

Ultimately, if he's decided that he's had enough and if it doesn't work for you, don't pay him: that's his decision. So if it doesn't work for you, you can decide to either not pay, or pay a partial amount and see if someone else wants to finish the job.

Ok thanks for the input

So I have made some changes but I am stuck on one part. I need to add a statement that says if the beam is reconnected during/before the 10 second initial timeout to cancel or do nothing. Im thinking a boolean would work? Basically if the countdown has not reached the 10 seconds that it would be false and therefore the rest of the code would not be ran. Would that work? If so, how do I do so?

Also I wanted to add some serial read functions to check the timing, I added the serial.begin but I am not sure where to add the serial.print to see the functions being timed.

//Diesels High Tech Pet beam break sensor
//This sketch activates and deactivates the "hold Up" function which is build into the HIGH TECH pet door
//By imitating pressing and holding "ON BUTTON" while pressing "OPEN BUTTON" and then releasing both buttons

enum State {
  IDLE, PAUSE_BEFORE_ON, ON_DELAY, OPEN_DELAY, WAIT_BEAM, PAUSE_BEFORE_CLOSE, OFF_DELAY
} state = IDLE;

uint32_t start_time;

const uint32_t PAUSE_BEFORE_ON_ms = 10L * 1000L; //pause for 10 seconds before initiating sequence
const uint32_t ON_DELAY_ms = 500L;  // pause for half a second before sending ON signal
const uint32_t OPEN_DELAY_ms = 500L;  // pause for half a second before sending OPEN signal
const uint32_t PAUSE_BEFORE_CLOSE_ms = 2L * 1000L; // pause for 2 seconds before sending ground signal to openPin which deactivates "hold Up" function
const uint32_t OFF_DELAY_ms = 250L;// pause for quarter of a second


const byte onPin = 2;    // On button
const byte openPin = 3;  // Open button
const byte beamPin = 4;  // QT50CM yellow wire of receiver

void activateButton(byte pin) {
  // to activate a button, we ground the pin
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
}

void deactivateButton(byte pin) {
  // to deactivate a button, we float the pin
  pinMode(pin, INPUT);
  digitalWrite(pin, LOW);
}

void setup() {

  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
  
  
  deactivateButton(onPin);
  deactivateButton(openPin);
  pinMode(beamPin, INPUT_PULLUP);  // turn on internal 5.1k pullup resistor

  state = IDLE;
  start_time = millis();
}

boolean beamIsBroken() {
  //'broken beam' grounds the output
  return digitalRead(beamPin) == LOW;

}




/**
  --wait for beam to break (IDLE)
  --beam breaks
  --wait 10 seconds  (PAUSE_BEFORE_ON)
  --send signal to ON
  --wait half a second  (ON_DELAY)
  --send signal to OPEN
  --wait half a second  (OPEN_DELAY)
  --release/turn off/float both signals
  --wait for beam to reconnect  (WAIT_BEAM)
  --wait another 2 seconds (PAUSE_BEFORE_CLOSE)
  --send ground signal to ON(which deactivates function)
  --wait 1/4 of a second (OFF_DELAY)
  --turn off "hold Up funtion" by sending ground signal to openPin
  --wait for beam to break again  (IDLE)
*/

void loop() {
  switch (state) {
    case IDLE:
      if (beamIsBroken()) {
        state = PAUSE_BEFORE_ON;
        start_time = millis();
      }
      break;

    case PAUSE_BEFORE_ON:
      if (millis() - start_time >= PAUSE_BEFORE_ON_ms) {
        activateButton(onPin);

        state = ON_DELAY;
        start_time = millis();
      }
      break;


    case ON_DELAY:
      if (millis() - start_time >= ON_DELAY_ms) {
        activateButton(openPin);

        state = OPEN_DELAY;
        start_time = millis();
      }
      break;

    case OPEN_DELAY:
      if (millis() - start_time >= OPEN_DELAY_ms) {
        deactivateButton(openPin);
        deactivateButton(onPin);

        state = WAIT_BEAM;
        start_time = millis();
      }
      break;

    case WAIT_BEAM:
      if (!beamIsBroken()) {
        state = PAUSE_BEFORE_CLOSE;
        start_time = millis();
      }
      break;


    case PAUSE_BEFORE_CLOSE:
      if (beamIsBroken()) {
        state = WAIT_BEAM;
        start_time = millis();
      }
      else  if (millis() - start_time >= PAUSE_BEFORE_CLOSE_ms) {
        activateButton(openPin);

        state = OFF_DELAY;
        start_time = millis();
      }
      break;


    case OFF_DELAY:
      if (millis() - start_time >= OFF_DELAY_ms) {
        deactivateButton(openPin);

        state = IDLE;
        start_time = millis();
      }
      break;
  }
}

diebog:
Also I wanted to add some serial read functions to check the timing, I added the serial.begin but I am not sure where to add the serial.print to see the functions being timed.

Please explain exactly what you want it to do. e.g. "When ... happens I want ... to be printed to Serial", etc.

I guess omit the serial for now. I just need to figure out how to stop the code if the 10 second timeout is not true. It still needs to check to see if the beam is broke or not, I just don't want the code that follows the 10 second timeout to function if the beam is reconnected in the 10 second window. How do I do that?.

Any one have an idea?

I tried this:

 boolean !beamIsBroken ;
      if !PAUSE_BEFORE_ON_ms() {
        state = IDLE;
        
      }
      break;

But it didnt work

diebog:

 boolean !beamIsBroken ;

That makes no sense. Maybe you meant:

if(!beamIsBroken()) {

The code inside that bracket will only run if beamPin is HIGH.

Ok thanks. So is the rest of the code okay?

All I want the program to do is this: if at any time during the 10 second count down you see beamPin high (beam connected) reset the loop. There has to be a simple way to do this.

diebog:
Ok thanks. So is the rest of the code okay?

No, this is completely wrong too:

diebog:

      if !PAUSE_BEFORE_ON_ms() {

You need to take some time to learn the basics of C++ instead of just typing out random stuff and hoping it might work purely by chance.

I have been watching some tutorials and I am learning, its just slow. I have this project I need to finnish badly. Can anyone help?

I tried this as well but it isnt resetting the loop back to idle like I want

//Diesels High Tech Pet beam break sensor
//This sketch activates and deactivates the "hold Up" function which is build into the HIGH TECH pet door
//By imitating pressing and holding "ON BUTTON" while pressing "OPEN BUTTON" and then releasing both buttons

enum State {
  IDLE, PAUSE_BEFORE_ON, ON_DELAY, OPEN_DELAY, WAIT_BEAM, PAUSE_BEFORE_CLOSE, OFF_DELAY
} state = IDLE;

uint32_t start_time;

const uint32_t PAUSE_BEFORE_ON_ms = 10L * 1000L; //pause for 10 seconds before initiating sequence
const uint32_t ON_DELAY_ms = 500L;  // pause for half a second before sending ON signal
const uint32_t OPEN_DELAY_ms = 500L;  // pause for half a second before sending OPEN signal
const uint32_t PAUSE_BEFORE_CLOSE_ms = 2L * 1000L; // pause for 2 seconds before sending ground signal to openPin which deactivates "hold Up" funtion
const uint32_t OFF_DELAY_ms = 250L;// pause for quarter of a second

const byte onPin = 2;    // On button
const byte openPin = 3;  // Open button
const byte beamPin = 4;  // QT50CM yellow wire of receiver

void activateButton(byte pin) {
  // to activate a button, we ground the pin
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
}

void deactivateButton(byte pin) {
  // to deactivate a button, we float the pin
  pinMode(pin, INPUT);
  digitalWrite(pin, LOW);
}

void setup() {
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

  deactivateButton(onPin);
  deactivateButton(openPin);
  pinMode(beamPin, INPUT_PULLUP);  // turn on internal 5.1k pullup resistor

  state = IDLE;
  start_time = millis();
}

boolean beamIsBroken() {
  //'broken beam' grounds the output
  return digitalRead(beamPin) == LOW;

}




/**
  --wait for beam to break (IDLE)
  --beam breaks
  --wait 10 seconds  (PAUSE_BEFORE_ON)
  --send signal to ON
  --wait half a second  (ON_DELAY)
  --send signal to OPEN
  --wait half a second  (OPEN_DELAY)
  --release/turn off/float both signals
  --wait for beam to reconnect  (WAIT_BEAM)
  --wait another 2 seconds (PAUSE_BEFORE_CLOSE)
  --send ground signal to ON(which deactivates function)
  --wait 1/4 of a second (OFF_DELAY)
  --turn off "hold Up funtion" by sending ground signal to openPin
  --wait for beam to break again  (IDLE)
*/

void loop() {
 
 
 switch (state) {
   if (state == PAUSE_BEFORE_ON) {

    //Wait in tight loop while counting down 10 second pause...
    while (millis() - start_time >= PAUSE_BEFORE_ON_ms) {

      //Check if BEAM is reconnected...
      //If it is, reset to IDLE mode
      if ( !beamIsBroken() ) {

        state = IDLE;
      }//close if
    }//close while
  }//close if
     
    
    case IDLE:
      if (beamIsBroken()) {
        state = PAUSE_BEFORE_ON;
        start_time = millis();
      }
      break;
 
    
    case PAUSE_BEFORE_ON:
      if (millis() - start_time >= PAUSE_BEFORE_ON_ms) {
        activateButton(onPin);

        state = ON_DELAY;
        start_time = millis();
      }
      break;



    case ON_DELAY:
      if (millis() - start_time >= ON_DELAY_ms) {
        activateButton(openPin);

        state = OPEN_DELAY;
        start_time = millis();
      }
      break;

    case OPEN_DELAY:
      if (millis() - start_time >= OPEN_DELAY_ms) {
        deactivateButton(openPin);
        deactivateButton(onPin);

        state = WAIT_BEAM;
        start_time = millis();
      }
      break;

    case WAIT_BEAM:
      if (!beamIsBroken()) {
        state = PAUSE_BEFORE_CLOSE;
        start_time = millis();
      }
      break;


    case PAUSE_BEFORE_CLOSE:
      if (beamIsBroken()) {
        state = WAIT_BEAM;
        start_time = millis();
      }
      else  if (millis() - start_time >= PAUSE_BEFORE_CLOSE_ms) {
        activateButton(openPin);

        state = OFF_DELAY;
        start_time = millis();
      }
      break;


    case OFF_DELAY:
      if (millis() - start_time >= OFF_DELAY_ms) {
        deactivateButton(openPin);

        state = IDLE;
        start_time = millis();
      }
      break;
  }



}

Goddamnit, diebog.

You just aren't getting that you don't pause or loop inside the state machine. For as long as the machine is in PAUSE_BEFORE_ON state, it executes that block of code in the case statement thousands of times a second until something else happens to change the state. This is caused by the fact that the underlying main() calls loop() over and over again, thousands of times a second. You don't pause that, or run a blocking while() statement. If you want the state to reset back to IDLE when the state is PAUSE_BEFORE_ON and the beam becomes unbroken, then that's exactly what you do. You handle that in tha block of code in the switch statement.

    case PAUSE_BEFORE_ON:
      if(!beamIsBroken()) {
        state = IDLE;
        start_time = millis();
      }
      else if (millis() - start_time >= PAUSE_BEFORE_ON_ms) {
        activateButton(onPin);

        state = ON_DELAY;
        start_time = millis();
      }
      break;

In any case, I'd just like to say to the rest of the board that the reason that I did not implement "if the beam becomes unbroken during the 10 second pause, then reset to IDLE" is that it was not part of the spec I was given.

The spec was:

diebog:
And instead of 2 seconds can we set it for 10 seconds. So once the beam is broke I want it to wait 10 seconds until it initiates the On-Open function.

and later:

diebog:
Once the beam is broken the following sequence happens:

It does nothing for ten seconds correct
Then the on button comes on (grounded) correct
then another 2 seconds 1 second or even half a second would work
then the open button comes on (grounded) correct
then … what? Both buttions are turned off immediately? Correct

And finally:

diebog:
Hi, I also forgot to mention that after the beam is reconnected that a signal needs to be sent to the OPEN button which in turn deactivates the function. Below is how I think it needs to work, I hope its not confusing.

beam breaks--wait 10 seconds--send signal to ON--wait half a second--send signal to OPEN--wait half a second--release/turn off/float both signals--if beam is still broke do nothing--if beam reconnects wait 2 seconds--send ground signal to ON for 1/4 of a second(which deactivates function)--wait for beam to break again

That's what I had to work with. To be perfectly fair, I have had a more confused client. I had to yell at that guy, too. Eventually told him, "look, I think the code will do everything you have said you wanted, have you tried it out?". Turned out, he hadn't. When he finall gave it a go, it worked perfectly.

That's not the case here, however. What's happening here is "Oh, and another thing …".

The thing is, my message to diebog was

--wait for beam to break (IDLE)
--beam breaks
--wait 10 seconds (PAUSE_BEFORE_OPEN)
--send signal to ON
--wait half a second (ON_DELAY)
--send signal to OPEN
--wait half a second (OPEN_DELAY)
--release/turn off/float both signals
--wait for beam to reconnect (WAIT_BEAM)
--wait another 2 seconds (PAUSE_BEFORE_CLOSE)
--send ground signal to ON(which deactivates function)
--wait 1/4 of a second (OFF_DELAY)
--turn off ON
--wait for beam to break again (IDLE)

I can edit my existing sketch to behave as described in this message for $50 payable by PayPal.

Diebog replied (eventually)

I guess I am going to just have to pay you to write this code for me.

And on that basis I proceeded to implement the sketch as agreed. I did so, and posted the message at the start of this unfortunate thread in reply. From there, you can read the rest of the story.

Notice that diebog is, in fact, trying to use my code. Now legally, I placed it in the public domain and people can as they wish. I have no recourse and realistically I am not going to attempt to sue someone in a whole different country for whom fifty bucks is a big deal. That's why I don't bother with attempting to license code I do on these forums - it's pointless. But ethically, diebog should either accept the work and pay me for my code, or write his own.

Now, you'll note that I actually have provided in this message, for free, a modification to my sketch to do the extra asked for. Why? Because I'm an old softie, that's why. But diebog could have gotten it with a lot less time and hassle if he'd nixed the whining about money for a week (adults understand that their problems are not other people's problems) and then paid me like he said he would for what we agreed I would do.

It seems to me that if the code provided met the specification then $50 AUD is a reasonable price. Embedded systems programming is a highly paid profession. Most developers wouldn't even consider doing a job for that price. The process of clarifying the specs for a job can be very time consuming and it's difficult to write code for a system you don't have access to for testing. If there was a problem in the code with onPin vs openPin it might be reasonable to expect that to be resolved but it seems like this may have been a miscommunication in the job spec rather than a bug. As for ongoing support and adding features, I'd say unless that was specified as part of the original contract then it should require additional payment if the developer chose to provide those services.

Also posted at Need some help on a beam break sensor code for Arduino - Stack Overflow
@diebog. If you're going to do that please add a link from each to the other to avoid duplicate effort. People may spend a lot of time reading through the code and providing an answer that had already been given on the other site.

I though that the 50$ covered additional help/modification to the code if further adjustments were needed.

This is one of the things you have to be really careful about on both sides. It's one thing if a Time & Materials payment method is agreed to, but for a fixed bid project, it's easy to lose money by doing this.

I have a good repeat client I met on here who generally requests modifications, but it's because English isn't his first language and he can't always explain exactly what he needs. He is very reasonable about what changes he asks for. If changes get to be too many, I request a higher fee.

For a $50 project, I'd be hard pressed to not stop after I deliver what's agreed upon and it's working. I'll certainly help you debug the wiring, but diebog, $50 is cheap. Sometimes that will barely buy a bag of groceries. I try very hard to give people value for their hard earned cash, but my time has value also. In my opinion, if PaulMurrayCbr's code did what you asked for initially, before changes were requested, you got a good deal. That's fairly complex behavior for just $50.

PaulMurrayCbr:
I have now adopted a personal rule - never directly reply to PMs containing questions about programming in a response PM - take it to a forum thread.

This is what very old moderators and star contributors of this forum do! cz they know its going to get outta control!