PIC programming

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Hi,
I have a suggestion for you to considered it. I used the zero crossing to turn ON/OFF all my amplifiers. This will minimized the inrush current when power it ON/OFF. You can easily do it by waiting for the zero crossing before turning ON/OFF relay 2. It will minimized the inrush current since you have a big amplifier. The zero crossing detector it is a simple circuit to implement and I can modify the software I am using for you application. Let me know if you are interesting.
 
Hi,
Attached it is the program file with some changes to the shutdown routine. Also I found the problem with the shutdown sequence. I was using increments "++" in the for/loop and should be decrements "--". Compare/check the changes with your last program. If you like the changes go ahead update them in your program or run the program to see if you like the changes to the program.
In the shutdown sequence you used delays turning off the relays. You do not suppose to shutdown the amplifier as soon as possible? Why the delays. Just a question.

They are very short delays they were not set yet, I'll delete the delays for relays 2&3, relay one does not matter. I'll want the caps to drain on the B+ before shutting off relay 1.
I'll give this a try on my breadboard.
I'll be making some circuit boards with relays, arduino and voltage dividers built to clean up the microprocessor area. Jeff sent me some Diptrace files I'll be changing to fit my amp. Did you do the same?

Hi,
I have a suggestion for you to considered it. I used the zero crossing to turn ON/OFF all my amplifiers. This will minimized the inrush current when power it ON/OFF. You can easily do it by waiting for the zero crossing before turning ON/OFF relay 2. It will minimized the inrush current since you have a big amplifier. The zero crossing detector it is a simple circuit to implement and I can modify the software I am using for you application. Let me know if you are interesting.

Interesting, how do you get zero crossing with a mechanical relay? Interest, tell me how you do it and I'll test it. I used zero crossing SS relays back in my lighting control days.
 
Last edited:
Hi,
Attached it is the modified program to use the zero crossing for power ON/OFF the amplifier to minimized the inrush current and the circuit for the the zero crossing interrupt. It is a simple circuit. In the way it works is by branching to an interrupt routine and wait until the zero crossing pulse arrived and then the interrupt routine will return back to the program at the right time to close/open the power relay. In the program I used the zero crossing to turn ON/OFF the amplifier and the filament relay. Also you can use the zero crossing to prevent the amplifier to turn ON itself after a power failure. Also I do that in all of my amplifiers but required a battery backup to allow the micro to setup the sequence after the AC power it is restore. Both options had been working flawless for 4 years without any problems. Let me know Let me know if you are interesting in the option to hold the power after a AC power failure. It is easily done by counting the zero crossing pulses for 2 cycles and if not then you prepare the program to do not allowed the program to turn ON the amp when the Ac power it is restore.
 

Attachments

  • Zero crossing.jpg
    73.9 KB · Views: 41
  • power_sequency_interruptable_1.txt
    7.6 KB · Views: 26
Member
Joined 2011
Paid Member
I finished my first microcontroller-based audio project a couple weeks ago. I discovered that if you buy the most recently introduced members of a microcontroller family, those chips are built on the newest "shrink" process technology, and so their chip size is tiny and they are extremely cheap. EXTREMELY cheap.

The one I chose was the newly announced PIC12F1571. In qty=1 it cost me USD 0.64 (GBP 0.42) from my preferred IC seller (link). Yes, yes, yes I could have saved even more money by using the SMD package, but the In Circuit Programming header would have increased the cost AND made the PCBoard larger.

Since I programmed it in C, most of the details of the instruction set architecture were unimportant to me. That's the compiler's job, not mine. I blithely declared a few variables to be unsigned 16-bit integers, and the compiler inlined the library code for 16 bit integer multiplication, on this 8-bit uC. Nice.
  • Delay_time = min_delay + (max_delay - min_delay) * (UserInput / 256)
Here's the thread that discusses the project, if anyone is interested (link 2)
 
How can I interrupt the startup sequence if I turn off the button during power_on sequence? I can add a line after each delay with an if power_button 0 then goto power down but the delays keep running in the back ground if I reset the power switch within the remaining delays.

Should I do a soft reset after the power down sequence? If I do that then the fault light would reset. I think it would be easier to do after each delay and add the "if power_button 0"

This code keeps running the delays even after the power off seq is executed.

void power_on_seq(){

if (flag == 1) return; {
digitalWrite(relay1, HIGH);
digitalWrite(standbyled, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
delay(9000); //relay 1 //90000 //Filament preheat
digitalWrite(relay2, HIGH);
if (digitalRead(power_switch) == 0) power_off_seq();
delay(3000); //relay 2 //90000 //Filament preheat
digitalWrite(standbyled, LOW);
if (digitalRead(power_switch) == 0) power_off_seq();
digitalWrite(relay3, HIGH);

And add this add the end of power off (add a check flag for the fault before executing or something)

void softwareReset( unsigned long delayMillis) {
uint32_t resetTime = millis() + delayMillis;
while ( resetTime > millis()) {
/* wait and do nothing until the required delay expires... */
}
// jump to the start of the program
asm volatile ( "jmp 0");
}
 
Last edited:
Hi,
That it is a problem when you used the delay() instruction. You need to let it finished. The problem it is when you have a delay like the 90000 delay. What I do when you need to do an long delay it is used a do loop delay like the example below. Used a small delay and loop it to give you the delay that you one. The example you will loop 200 time of 5 and if the switch it is = 1 then the loop will exit.

int delay_count = 200 // set it up by delay(5) * 200 = 1000 seconds

void delay_routine()
do {
delay(5); //do small delay
delay_count = delay_count +1;
if (digitalRead(power_switch) == 1) return;
}while (delay_count == 5000)
 
Member
Joined 2011
Paid Member
I think the program in #71 might not be correct. If you begin with "delay_count = 200" then you want to decrement the variable named delay_count until it falls to zero or below. That way you call the delay(5) subroutine, exactly 200 times.

Instead the program in #71 increments the variable named delay_count until it equals 5000. This means you call the delay(5) subroutine, exactly 4800 times. I don't think that is what you want.
 
Hi,
Yes you are right it should be 200. I forget the delay = 5. Also it should be less than 200. Thank for the correction . Also I added another variable so you can use the routine for all the delays. Just change the end _delay to the delay you want.

int end_delay = 200 //add this variable so you can use the routine for the delays.
int delay_count = 0

do {
delay(5) ; //do small delay
delay_count = delay_count +1;
if (digitalRead(power_switch) == 1) return;
}while (delay_count < end_delay )
 
Hi,
Yes you are right it should be 200. I forget the delay = 5. Also it should be less than 200. Thank for the correction . Also I added another variable so you can use the routine for all the delays. Just change the end _delay to the delay you want.

int end_delay = 200 //add this variable so you can use the routine for the delays.
int delay_count = 0

do {
delay(5) ; //do small delay
delay_count = delay_count +1;
if (digitalRead(power_switch) == 1) return;
}while (delay_count < end_delay )

That didn't work, does this get inserted once? Its stuck in a delay loop
I wanted a different delay for each relay. I'm experimenting with my power on sequence file (see attached) right now in lieu of string(until I get the jist)
 

Attachments

  • Delays.txt
    3.8 KB · Views: 28
Last edited:
millis seems like a good method but I'm lost after reading the Arduino explanation and where to insert the different delays (see file on #76). Attached my half *** attempt
The other problem is I don't want to start looking at the shutdown routine loop until after the last relay is energized
I'm juggling building an amp and learning to write Arduino code. I at least want to get the code safe enough to run the amps startup without any mishaps and work on the bells and whistles later. I ended up with 4 relays since I have two power supplies in each amp.
Millis would allow me to do an emer off without waiting for a timer.
 

Attachments

  • millis Delays.txt
    4.3 KB · Views: 29
Last edited:
Declare your delay variables first. They need to be "long" because of their size.

long tubeheaterDelay = 90000 // 90second tube preheat
long inrushDelay = 3000 // 3 second inrush relay operation
long debounceDelay = 50 // 50ms debounce delay
ect

You need to declare millis as an "unsigned long" because it eventually reaches it's limit and starts over as a negative number.

unsigned long currentMillis = 0 // this can be named anything. currentMillis is easy.

In your function calls you will need to record when you used millis as a time refernce

long previousMillis = 0 // this starts at 0 when the software starts, but will be updated regularly in the void loop

In you function calls, assign currentMillis to the actual millis

currentMillis = millis

if(currentMillis - previousMillis > tubeHeaterDelay) { // is now - the last time it reset greater than tubeHeatDelay?
previousMillis = currentMillis; // this restarts the timer for the next function
digitalWrite (whatever relay pin, HIGH);
}
 
Last edited:
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.