PIC programming

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Yes, I get the part about writing a variable for each delay. Then use the delay name in an "if" statement to execute the next relay?
I would of used your board but my amp is not your typical tube amp. It has a couple power supplies and each one needs to be delayed, 400 and 1200vdc is not forgiving if something were to happen. So I needed to setup 4 relays for the sequence and then start reading the voltage divider network immediately after the last relay.
That would be 3 delays after first relay energizes, #1 about 45 seconds/#2 about 30 seconds/#3 about 3-4 seconds

long heatingDelay = 40000; // wait for tubes pre-heating (mS)
long driverDelay = 20000; // wait for HV retifiers to heat, turn on driver HV (mS)
long softstartDelay = 3000; // softstart delay (ms)

Implemented in this sequence

void power_on_seq(){

if (flag == 1) return; {
digitalWrite(relay1, HIGH);
digitalWrite(standbyled, HIGH);
if (digitalRead(power_switch)== 0 && on_off_flag == 1) power_off_seq();
digitalWrite(relay2, HIGH);
delay(9000); //90000 //B+ to 2A3, 6AX4 filament preheat delay
if (digitalRead(power_switch)== 0 && on_off_flag == 1) power_off_seq();
digitalWrite(relay3, HIGH);
delay(3000); //90000 //GM70 B+ Softstart delay
if (digitalRead(power_switch)== 0 && on_off_flag == 1) power_off_seq();
digitalWrite(standbyled, LOW);
digitalWrite(relay4, HIGH);

}

on_off_flag = 1;
}
 
Last edited:
Hi,
I found the problem but I do not know why does not worked like it is suppose to. In the if statement you can not put the return in the same line'.
Here it is the code if you want to use it. It will stop the delay immediately if you turn off power switch. It is up to you to use it. Also remove the print statement after you test it. I use them fro troubleshoot the program.

/************************************
int power_switch = 7 ; switch input port
int end_delay ; //Used to set the delay
void setup() {
// put your setup code here, to run once:
pinMode(7, INPUT);
Serial.begin(9600);

}

void loop() {
// put your main code here, to run repeatedly:
end_delay = 200; delay_sub(); //set delay time for every delay
Serial.println("start");

}
//****************** delay routine *****************
/* to use this routine you need to define the end_delay variable
at the beginning of the program. Set number for the delay that you
want and then branch to the delay routine*/

void delay_sub(){
int delay_count= 0 ;
do{
delay(5) ; //do small delay
delay_count = delay_count + 1;

if (digitalRead(power_switch) == 0)
{
Serial.println("Abort routine "); return;
}

}while (delay_count < end_delay );
Serial.println("Time out ");
}
//*****************************************************************
 
You lost me in the delay routine.
Does this get inserted after every digitalWrite to relay?
I don't think I understand how to "branch to delay routine"

void power_on_seq(){

if (flag == 1) return; {
digitalWrite(relay1, HIGH);
digitalWrite(standbyled, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
digitalWrite(relay2, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
delay(18000); //90000 //B+ to 2A3, 6AX4 filament preheat delay
digitalWrite(relay3, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
delay(3000); //90000 //GM70 B+ Softstart delay
digitalWrite(standbyled, LOW);
digitalWrite(relay4, HIGH);
digitalWrite(HVled, HIGH);
 
Last edited:
Hi,
Here it is how you do it. Just load the delay variable number for the delay and branch to the routine.

/* For the delay routine to work when the switch ON = 1 power ON
* switch OFF = 0 power off
*/

//*******************************Warning ***********************************
int end_delay = 0 /*<<<<<<<<<<<<<<<<<< you need to declare this variable
at the beginning and load it with the delay number before you branch
to the delay routine. You can rename the variables with the name that suit you */
//***********************************************************************************
void power_on_seq(){

if (flag == 1) return; {
digitalWrite(relay1, HIGH);
digitalWrite(standbyled, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
digitalWrite(relay2, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
//***************************************************************************************
end_delay = 1800); delay_sub() //90000/5 //B+ to 2A3, 6AX4 filament preheat delay
//***************************************************************************************
digitalWrite(relay3, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
//**************************************************************************************
end_delay = 600; delay_sub(); //3000/5 //GM70 B+ Softstart delay
//**************************************************************************************
digitalWrite(standbyled, LOW);
digitalWrite(relay4, HIGH);
digitalWrite(HVled, HIGH);
//***************************** delay routine ********************
void delay_sub(){
int delay_count= 0 ;
do{
delay(5) ; //do small delay
delay_count = delay_count + 1;
if (digitalRead(power_switch) == 0){ Serial.println("delay abort");return;}
}while (delay_count < end_delay );
}
//*****************************************************************
 
So I added the int end_delay in variables

Then I added a separate delay routine in which I added to the void loop()
*************************
// put your main code here, to run repeatedly:
void loop(){
read_switch();
shutdown_routine();
led_statuslights();
delay_sub();
}

***********************


Then I added the power on routine (you forgot the filament preheat line) and I changed the delays.
You also had some of the curly braces and lack of end statements (which has been a learning experience). But it seemed to work except for one little bug.
If I change the state of switch to 0 during power up on relay1, relay2 toggles on for a second and then turns off with 1. This does not happen once relay 2, 3 or 4 are energized (I guess because 2 is already on). If I remove the delays in the off seq, relay2 will not bounce on. I really needed relay 1 to stay (without relay2 bounce) on for a few seconds to let B+ drain off the plates. Took out all the delays except between 2 and 1 to solve the problem.

//***************************** delay routine ********************
void delay_sub(){
int delay_count= 0 ;
do{
delay(5) ; //do small delay
delay_count = delay_count + 1;
if (digitalRead(power_switch) == 0){ Serial.println("delay abort");return;}
}while (delay_count < end_delay );
}
//************************************************** ***************
void power_on_seq(){

if (flag == 1) return; {
digitalWrite(relay1, HIGH);
digitalWrite(standbyled, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
//************************************************** *************************************
end_delay = 8000; delay_sub(); //40000/5 // filament preheat delay
//************************************************** *************************************
digitalWrite(relay2, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
//************************************************** *************************************
end_delay = 4000; delay_sub(); //20000/5 //B+ to 2A3, 6AX4 filament preheat delay
//************************************************** *************************************
digitalWrite(relay3, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
//************************************************** ************************************
end_delay = 800; delay_sub(); //3000/5 //GM70 B+ Softstart delay
//************************************************** ************************************
digitalWrite(standbyled, LOW);
digitalWrite(relay4, HIGH);
digitalWrite(HVled, HIGH);

}

on_off_flag = 1;
}

Anyways, the sequence seems to be fool proof to the point I can fire up the amp(without the variac).
Thanks for the help.
-------------------------------------
Jeff, I tried the millis out and got the code to finally compile (after extensive tweaking) but it doesn't work.
I'd like to learn millis and will do some more studying over the weekend. Using the milli method, I may have to rethink the entire startup and shutdown sequence and probably need to use "State" of relays like in the code used for your boards. (which I'm waiting for your beta testing thumbs up).

Once I get these amps finished, I'll be taking some more youtube Arduino lessons for future enhancements.
 
The control board and relay boards are working perfectly. I haven't tested the high voltage detection board yet. I've got boards,but haven't populated them yet to test. I think I have some part values messed up on it though. Hold off on it.

I'll try to put together some software for your application. Vzaichenko has commented his code fairly well, so it shouldn't be hard to add another state to it. The speaker protection interrupt will work perfectly for your over-voltage protection.
 
Hi,
OooPPPSS. You know what it is the problem. The problem it is that it will abort the first delay but go to second and the third. We need to change instead do the return send it to the "read_switch()" in this way it will terminate the start up routine completely. Change the instruction from
if (digitalRead(power_switch) == 0){ return;} to
if (digitalRead(power_switch) == 0){read_switch();} // this will send the program to read the switch and forget turn on the other 2 relays.
 
Hi,
OooPPPSS. You know what it is the problem. The problem it is that it will abort the first delay but go to second and the third. We need to change instead do the return send it to the "read_switch()" in this way it will terminate the start up routine completely. Change the instruction from
if (digitalRead(power_switch) == 0){ return;} to
if (digitalRead(power_switch) == 0){read_switch();} // this will send the program to read the switch and forget turn on the other 2 relays.

I tried that, its not as reliable, relay 2 and 3 toggle quickly if I do a short power cycle (on/off/on) during relay 1 delay.

Also found a bug in post 87 code, if I power cycle quickly during relay1 delay (on/off/on), relay4 energizes, NOT GOOD AT ALL (1200v transformer)
I also tried to add it before or after the first line using your read_switch and relay4 still comes on. This does not happen in the remaining relay sequence.
 
Last edited:
Hi,
for a better exit do the change it to read the switch first to abort the delay then do delay after that. It will abort the 2 and 3 relay without doing the 5 seconds delay. That it is what you noticed. You should exit the routine by a return.


//***************************** delay routine ********************
void delay_sub(){
int delay_count= 0 ;
do{
if (digitalRead(power_switch) == 0){return;}
delay_count = delay_count + 1;
delay(5) ; //do small delay
}while (delay_count < end_delay );
}
//*****************************************************************
 
Hi,
I spent 40 minutes looking why the iIf statement command in the delay routine didn't work without {}. Finnaly fixed by adding the {return}. I was following their reference example that suppose to worked without the brackets {}. Like their example "if (x > 120) digitalWrite(LEDpin, HIGH);" This does not worked. My problem with the Arduino commands it is follow "{}" and the ";" semicolon at the end of the command. If you missed then it will give you an error that point to some places in the program. I ate them. Normally I used the Basic micro and the Zbasic micro in all of my projects. Now I am learning the Arduino because you can buy the board for less that $5 dollars.
 
The IDE is finding the error while trying to compile the code into machine code. A lot of times when you make an error at one place, the IDE will continue compiling, but it gets redirected to another area of the code before it can't go any farther. This is a real PITA when you have 6 tabs of function calls. The error might not be on the same tab as it's showing.
 
Discovered another bug. If I interupt the startup (with power button) during heating cycling, all relay toggle on for a second, then off.

Also, if I power off and wait a couple minutes to repower, all 4 relays turn on bypassing any delay
 

Attachments

  • Rev3 problem.txt
    4.5 KB · Views: 30
Last edited:
Hi,
I think I misunderstood the return instruction. It will not exit the "power_on_seq" just the delay sub routine. Any way I added a "dly_flag" variable that you set when you exit the delay routine thru the return and if = 1 then you exit the "power_on_seq". What happened it is followed the next delay after aborted the first delay routine. Try it and see if the modification works. Attached it is the modified file. I didn't try it I got the free windows 10 and I am learning it yet. I was using windows 7 and it is a big changed.
 

Attachments

  • Rev4problem.txt
    4.5 KB · Views: 46
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.