Help a rookie with a program

rob53

New Member
Hey guys, I'm back again needing more help. For those that don't know me, I am primarily a modeler. I got into hobby electronics because I wanted to add some lighting effects to some of my models. I am currently building this huge 1/350 scale model of the starship enterprise. It is the "refit" enterprise from the first star trek movie released in 1979. This thing is 34" long when fully assembled. It is actually designed for lighting. I have a program that Hippy helped me with about 12 years ago. I'm wanting to add another little feature to it, but I can't figure out how to go about it. Here is the part of the original code that's relevant without the feature added. The rest of the code is not at all related to my problem. This code (under Deflector) controls a bluee/yellow bicolored LED. At the first push of the button the LED ramps up in Yellow. The second button push ramps up the Blue, then fades out the yellow, giving it the appearance that its morphing from yellow to blue. The third press of the button fades off the Blue LED, then it's resets the variable and loops.

Code:
#Picaxe 14M2 USS Enterprise NCC-1701 Lighting FX

Symbol switchA = pinC.4
Symbol switchB = pinC.3

Symbol buttonA = b0
Symbol ButtonB = b1
Symbol pwmA = w1
Symbol pwmB = w2
                 
; ====== Button Handler ===================

Start0:
  Do
    If switchA = 1 Then : Resume 1 : End If
    If switchB = 1 Then : Resume 2 : End If
    Pause 50
 Loop

; ====== Deflector ========================

Start1:
  Do
    Suspend 1
    buttonA = buttonA + 1
  Select Case buttonA
      Case 1
        PwmOut PWMDIV4, C.0, 99, 0
        For pwmA = 0 To 400
        PwmDuty C.0, pwmA
        Pause 2
        Next
      Case 2
        PwmOut PWMDIV4, C.2, 99, 0
        For pwmA = 0 To 400
        PwmDuty C.2, pwmA
        Pause 2
        Next
        For pwmA = 400 To 0 Step -1
        PwmDuty C.0, pwmA
        Pause 2
        Next
        PwmDuty C.0, 0
      Case 3
        For pwmA = 400 To 0 Step -1
        PwmDuty C.2, pwmA
        Pause 2
        Next
        PwmDuty C.2, 0
        buttonA = 0
     End Select
 Loop

Here is the modified code I attempted to make, I have 6 outputs going high at 1 second intervals, then the bi-colored LED ramps up in yellow. I'm wanting to sort of recreate a scene in the movie when the ship first powers up getting ready to leave the space dock. I even have a sound module that plays the music from that scene while it's powering up.

Code:
#Picaxe 20M2 08M2 Enterprise Refit Lighting FX

Symbol switchA = pinC.7
Symbol switchB = pinC.6

Symbol buttonA = b0  
Symbol ButtonB = b1
Symbol pwmA = w1
Symbol pwmB = w2
 
; ====== Button Handler ===================

Start0:
  Do
    If switchA = 1 Then : Resume 1 : End If 
    If switchB = 1 Then : Resume 2 : End If
    Pause 50
 Loop

; ====== POWER-UP ========================

Start1: 
    Do
      Suspend 1
    buttonA = buttonA + 1
  Select Case buttonA
      Case 1
     High C.0
     Pause 1000
       High C.1
     Pause 1000
      High C.4
    Pause 1000
     High B.5
   Pause 1000
     High B.6
   Pause 1000
     High B.7
   Pause 1000  
  PwmOut PWMDIV4, C.2, 99, 0
        For pwmA = 0 To 400
        PwmDuty C.2, pwmA  
        Pause 2
        Next
      Case 2
        PwmOut PWMDIV4, C.3, 99, 0
        For pwmA = 0 To 400
        PwmDuty C.3, pwmA
        Pause 2
        Next
        For pwmA = 400 To 0 Step -1
        PwmDuty C.2, pwmA
        Pause 2
        Next
        PwmDuty C.2, 0
     Case 3
        For pwmA = 0 To 400
        PwmDuty C.2, pwmA
        Pause 2
        Next
        For pwmA = 400 To 0 Step -1
        PwmDuty C.3, pwmA
        Pause 2
        Next
        PwmDuty C.3, 0
        buttonA = 0
     End Select
loop

What I'm really wanting to achieve, is, at the first button press, is to have all the spot lights (the 6 outputs) come on in 1 second intervals, then the yellow side of the LED ramps up (the deflector dish), then with every subsequent button press the LED alternates between blue and yellow, the blue /yellow bi-colored LED and the spotlights stay on for as long as the circuit is powered up. I know how to design the circuit board using a program called KiCad, then upload the design to a company online that will make the boards for me. All I need is the proper code to achieve what I'm wanting. Any help someone can give me with this would be greatly appreciated. Thank you very much in advance.
 
Rob,

Just reading the code I can't see anything wrong.

Does the unmodified code (without the spot lights) work correctly?

Describe what actually happens with the modified code when you power on the circuit and then press the button the first, second, third and fourth time that is different from the unmodified code and different from what you want.
 
Last edited:
Hi,

As far as I can see (with no circuit diagram) the LED was being operated by the PWM Hardware in "Bridge Mode" across pins C.0 and C.2. Your modified Program seems to refer to pins C.2 and C.3 ? But the PWM can be used only on the Specific pins that connect to the Internal Hardware circuit, which for the 14M2 is C.0 , C.2 , B.2 and B.4 (perhaps see User Manual 1, page 10, depending on the issue version). You probably can't even use every permutation of those 4 PWM pins, because they may need to be on "opposing" sides of the bridge configuration. Is there a vital reason why you've moved away from using pins C.0 and C.2 for the LED ?

EDIT: Ah, it looks as if you're changing from a 14M2 to a 20M2 ? The PWM pins on the 20M2 are C.2 , C.3 , C.5 and B.1 but the Internal Hardware connections are not necessarily in the same sequence (and there is also an "Alternate Pin Function" register in the firmware for 4 other pins). It should be possible to predict the correct pins from the Microchip Data Sheet, but it's very complicated with the details spread over 400+ pages, so I'm not going to try until the issue is confirmed. Even then, it will be essential for you to check the function on real prototype hardware.

Also, are you (now) using any Servos? From Manual 2 for PWMOUT , "14M2 : pins C.0 , C.2 share the servo timer" and "20M2 : pins C.3 , C.5 share the servo timer"?

Cheers, Alan.
 
Last edited:
Hi Alan, I really don't understand any of that. I think this is just a simple problem of coding it correctly. It has nothing to do with internal hardware etc., but to answer your question, no, there are no servos, that was a different build (USS Voyager). This is the 1/350 scale USS Enterprise (Refit) There are no moving parts on this model.


Hi Flenser, thank you for responding. When I press the button the first time, the 6 spotlights come on just like I want them to and the yellow ramps up just like I want , then the 2nd press, the blue ramps up yellow fades out (morphing to blue) again, just like I want. Third button press, it morphs back to yellow, just like I want, but the 4th button press, it pauses a few seconds, as if its going through the motions of lighting the spotlights again, then the yellow side blinks off and quickly ramps back up, like the pwm is fading it on again. When it "loops" it carries out that first command again, lighting the spotlights when they're already lit, and ramping up the yellow when its already lit.

Here is the best way I can explain what I want it to do.
Case ! = spotlights come on in one second intervals, then yellow (C.2) ramps up.
Case2 = Blue (C.3) ramps up, yellow fades off (morphing from yellow to blue)
Case3 Yellow ramps up, blue fades off (morphing from blue to yellow)

I want it to keep alternating between yellow and blue after the spotlights come on and the yellow has ramped up. I think it needs a "goto" and then set up the alternating PWM sequence there, but I don't know how to set that up. I tried using a goto start5, but it didn't work, because I don't know what the hell I'm doing.. Here is the entire program (modified). all it's doing is controlling a bunch of leds, nothing complicated.

Code:
#Picaxe 20M2 08M2 Enterprise Refit Lighting FX

Symbol switchA = pinC.7
Symbol switchB = pinC.6

Symbol buttonA = b0  
Symbol ButtonB = b1
Symbol pwmA = w1
Symbol pwmB = w2
 
; ====== Button Handler ===================

Start0:
  Do
    If switchA = 1 Then : Resume 1 : End If 
    If switchB = 1 Then : Resume 2 : End If
    Pause 50
 Loop

; ====== POWER-UP Spotlights, Deflector Dish, Impulse Power & Warp Engines ========================

Start1: 
    Do
      Suspend 1
    buttonA = buttonA + 1
  Select Case buttonA
      Case 1
     High C.0
     Pause 1000
       High C.1
     Pause 1000
      High C.4
    Pause 1000
     High B.5
   Pause 1000
     High B.6
   Pause 1000
     High B.7
   Pause 1000  
   PwmOut PWMDIV4, C.2, 99, 0
        For pwmA = 0 To 400
        PwmDuty C.2, pwmA  
        Pause 2
        Next
      Case 2
        PwmOut PWMDIV4, C.3, 99, 0
        For pwmA = 0 To 400
        PwmDuty C.3, pwmA
        Pause 2
        Next
        For pwmA = 400 To 0 Step -1
        PwmDuty C.2, pwmA
        Pause 2
        Next
        PwmDuty C.2, 0
     Case 3
        For pwmA = 0 To 400
        PwmDuty C.2, pwmA
        Pause 2
        Next
        For pwmA = 400 To 0 Step -1
        PwmDuty C.3, pwmA
        Pause 2
        Next
        PwmDuty C.3, 0
        buttonA = 0
     End Select
 Loop  
       
    
    ; ====== L & R Torpedo ===========================

Start2:
    Do
    Suspend 2
    buttonB = buttonB + 1
   Select Case buttonB
     Case 1
        PwmOut PWMDIV4, C.5, 99, 0
        For pwmB = 0 To 200
        PwmDuty C.5, pwmB
          Pause 2
     Next
        High B.2
        Pause 50
        Low B.2
        Pause 50
        High B.2
        Pause 50
        Low B.2
        Pause 50
        High B.2
        Pause 50        
      Low B.2
        For pwmB = 200 To 0 Step -1
       PwmDuty C.5, pwmB
        Pause 2
        Next
        PwmDuty C.5, 0
     Case 2
        PwmOut PWMDIV4, B.1, 99, 0
        For pwmB = 0 To 200
          PwmDuty B.1, pwmB
          Pause 2
       Next
        High B.4
        Pause 50
        Low B.4
        Pause 50
        High B.4
        Pause 50
        Low B.4
        Pause 50
        High B.4
        Pause 50
        Low B.4
      For pwmB = 200 To 0 Step -1
        PwmDuty B.1, pwmB
        Pause 2
        Next
        PwmDuty B.1, 0
        buttonB = 0
    End Select
 Loop

; ======== Nav Lights =========================

start3:
  Do
    high B.0
    pause 1500
    low B.0
    pause 1500
  loop

; ======= strobe ==============================

start4:
Do
  High B.3
  pause 20
  low B.3
  pause 1000
Loop
 
Hi,

I think this is just a simple problem of coding it correctly. It has nothing to do with internal hardware etc., .....
Code:
#Picaxe 20M2 ;  08M2 Enterprise Refit Lighting FX
......
   PwmOut PWMDIV4, C.2, 99, 0    [ ; An instruction to the Background HARDWARE ]
......

The Blue/Yellow LED dimming/control uses the PWM Internal Hardware (in a "Bridge" driven from two pins), so IMHO this is very probably a Hardware Design issue. Fortunately, I believe it can be solved with quite small changes to the design/software:

For the "Bridge" to work correctly, the two pins must be driven at the same frequency (and appropriate DUTY periods). I don't know if hippy chose C.0 and C.2 for the LED connections on the 14M2, or if it was just "luck", but my Edited text in #3 shows that these pins use the same oscillator **. For the 20M2, the equivalent pins appear to be C.3 and C.5 , so can you try changing the test hardware and program to use those pins (for the Blue/Yellow LED(s) and see if it works?

If this works, but you are already committed to other PWM pins then it might be possible to adapt the Program alone (but it probably won't be easy).

** From the PWMOUT documentation in the PICaxe User Manual (2), etc.:

* On older PICAXE parts the same internal timer (timer2) is used for both pwmout and servo, so these commands cannot be used at the same time. However some newer parts have additional dedicated internal timers that allow pwmout and servo to work together. This applies to these pwmout channels:
14M2 B.2, B.4 (C.0, C.2 share the servo timer)
18M2 B.3, B.6
20M2 B.1, C.2 (C.3, C.5 share the servo timer)
28X2 B.0, B.5 (C.1, C.2 share the servo timer)


Cheers, Alan.
 
Rob,

Your explanation of the behaviour you want is clear, and I can see how your code is intended to match your description.

As I understand your explanation I think the issue is that case 1 should only be executed the first time you press the button.
- You never want to turn the spotlights on again
- You never again are in the state where the yellow and blue leds are both off and you want to ramp the yellow led up from 0 to fully on.

To get you started try changing the code for Start 1 to this below:
- What was the case 1 code to turn on the spotlights and change from the yellow and blue leds both off to ramp the yellow led up from 0 to fully on is taken out of the loop and out of the case statement. This means that what was the Case1 code only executes only the first time Start1: is resumed. Start1 never again executes this code.
- The case statement is altered to only run your original cases 2 & 3, which are renumbered as 1 & 2.
- After the original case 1 code runs the first time the button is pressed the program execution falls through to the do loop and the first command in the loop is another suspend. This means that Start1 is suspended at the start of the loop waiting for the 2nd, 3rd, 4th, etc button presses.
- The subsequent button presses will alternate between the code for the original cases 2 & 3, so the leds will morph from yellow to blue then from blue to yellow then back around the loop to morph from yellow to blue, etc as the buttons is pressed.

The example code in the manual for the PwmOut command has PwmOut being executed once as a part of the init section while you code repeatedly executes the PwmOut initialization each time the button press triggered the original case 2 & 3 code.
- I don't know if this matters but in my code below have moved the two PwmOut commands into the top of my modified Start1 code where they will only ever be executed once the 1st time the button is pressed.

Code:
Start1:
      Suspend 1     ; Suspend Start1 until we get the 1st button press

     ; The 1st button press
     ; turn on the spotlights
     High C.0
     Pause 1000
       High C.1
     Pause 1000
      High C.4
    Pause 1000
     High B.5
   Pause 1000
     High B.6
   Pause 1000
     High B.7
   Pause 1000 

   ; Run PwmOut commands to initialize PWM on C.2 & C.3 and setting the duty to 0 for both
   PwmOut PWMDIV4, C.2, 99, 0
   PwmOut PWMDIV4, C.3, 99, 0

   ; Ramp the yellow led from 0 to fully on
   For pwmA = 0 To 400
   PwmDuty C.2, pwmA 
   Pause 2
   Next

   ; Enter the DO loop ,which suspends Start1 waiting for the 2nd, 3rd, 4th, etc button presses.
   Do
      Suspend 1     ; Suspend Start1 until we get the next button press
    buttonA = buttonA + 1
  Select Case buttonA
      Case 1
       ; The yellow led is on and the blue led is off
       ; Ramp the blue led from 0 to fully on
        For pwmA = 0 To 400
        PwmDuty C.3, pwmA
        Pause 2
        Next
       ; Ramp the yellow led from fully on to 0
        For pwmA = 400 To 0 Step -1
        PwmDuty C.2, pwmA
        Pause 2
        Next
        PwmDuty C.2, 0
     Case 2
       ; The blue led is on and the yellow led is off
       ; Ramp the yellow led from 0 to fully on
        For pwmA = 0 To 400
        PwmDuty C.2, pwmA
        Pause 2
        Next
       ; Ramp the blue led from fully on to 0
        For pwmA = 400 To 0 Step -1
        PwmDuty C.3, pwmA
        Pause 2
        Next
        PwmDuty C.3, 0
        buttonA = 0
     End Select
 Loop
 
Hi,

Yes, having read through the whole program, I agree that the analysis offered by flenser is probably correct and his changes may help to "tidy up" the overall program.

However, it looks to me that the problem could be checked and cured by simply changing the penultimate line of the "Start 1:" loop of the program from buttonA = 0 to buttonA = 1 (which becomes incremented to 2 on the next button-push and then executes only Case 2 and Case 3 as before). ;)

Cheers, Alan.
 
Responding to Alan, from post #5: Yes Alan, I understand that the program is being "handled" by the hardware inside the chip. I may be an idiot when it comes to programming, but I'm not that inept. I do understand the inherent relationship between hardware and software. I am fully capable of building a desktop computer (for, but not limited to, gaming) from scratch parts that I acquire from Newegg.com. I can build a gaming PC. as much or more powerful than the most powerful Alienware computer you can buy, but at a fraction of the cost ;)

Responding to Alan from Post #7: You know, that makes a lot of sense. I will try it. **Tried it** It works. After the initial button press activates the spotlights, and the yellow ramps up, the yellow and blue just keep alternating, which is exactly what I wanted

To Flenser. That gives me a much better understanding of why Hippy setup the (unmodified) version of the program that I've been using. I had written the program using the "if, then, else" statements, but I was having some trouble, and Hippy responded explaining another way to do it, but I told him that I was basically just a modeler, and really didn't have the programming skill to implement his suggestion, and god bless him, he just wrote it for me. But I wasn't aware that a task(s) could be carried out without a Case statement (or button press) in front of it. The way you're doing it, Start1 is implementing the spotlights after a button press has "resumed" Start1, but outside of the "Do Loop", that is such an obvious solution that I never would have thought of. You guys have a brain that works differently than mine, or I probably need more experience or maybe some formal education in the fundamentals of programming. I will make the change and let you know.

***Made the change*** You solution works flawlessly as well, Flenser and although Alan's solution was much simpler, your solution gave me a better understanding of how I can use the "Suspend/Resume" and "Select Case" statements.

I learned a lot here today, guys. Again, Flenser and Alan thank you so much for helping me AGAIN.
 
Back
Top