Announcement

Collapse
No announcement yet.

Is anyone here an expert in PIC?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #46
    I spent hours on this today trying to fathom out the delay - whatever I tried, in whatever order, the delay was the same. I read your latest post and cross referenced the timeout; you're spot-on - pulseIn blocks code execution for a default which is 1 second, after which it returns zero if no input is detected. As soon as I set my own timeout everything worked just fine. The gate signal is perfect. Really snappy with sensing the guitar and no glitching as the note fades or when damped. Can't wait to build the revised input circuit.

    The change needed was:

    Htime = pulseIn(guitar_in, HIGH, 5000UL); // read high time
    Ltime = pulseIn(guitar_in, LOW, 5000UL) ; // read low time​

    I just set an arbitrary 5000 microseconds as a test but it seems to work really well at that.

    EDIT: I noticed the LED wasn't as bright as it was previously and the timeout needed to increase to 15000 to prevent the LED and gate pins from strobing on low frequencies.
    Last edited by Mick Bailey; 09-03-2023, 07:29 AM.

    Comment


    • #47
      Originally posted by Mick Bailey View Post
      I noticed the LED wasn't as bright as it was previously and the timeout needed to increase to 15000 to prevent the LED and gate pins from strobing on low frequencies.
      You may need to increase the timeout if you want to capture a 65Hz frequency because pulseIn needs to see a transition in order to trigger. In a worst case scenario you just missed the transition and would have to wait an extra full cycle to see it. So 30000? This shouldn't introduce any delay because the timeout is only reached if there are no transitions.

      Comment


      • #48
        20000 was needed to completely eliminate strobing - there was still a problem with low E with a value of 15000. The only thing the value seems to affect is turning off the gate, but 20ms from the note ending to gate-off is just fine - all lost in the synth's envelope generators. Hopefully the parts should turn up this week to build a new fundamental extractor. When its all properly working I'll do some sound clips.

        Comment


        • #49
          If voltage is positive then the next full pulse will be negative. If Htime and Ltime are essentially equal then you can measure just one of them and double the result.

          Ttime = 2 * pulseIn(guitar_in, LOW, 20000UL) ; // read time​

          Instead of LOW you could put a conditional that tests the voltage. My guess is that LOW is false and HIGH is true but I will leave that to you to look up.

          Ttime = 2 * pulseIn(guitar_in, conditional statement, 20000UL) ; // read time​

          Comment


          • #50
            That makes sense - the blocking is then halved. I need to scope the output of the fundamental extractor to be certain of a 1:1 square wave ratio.

            Comment


            • #51
              Got rid of a multiplication.

              Halftime = pulseIn(guitar_in, conditional statement, 20000UL) ; // read time​
              frequency55 = 9091 / Halftime; // calculate frequency

              It occurs to me that there may be an additional time savings because measuring a HIGH and a LOW may require an additional wasted cycle in-between.

              This way we just use the voltage to tell us whether a HIGH or LOW is next.
              Last edited by Pixel; 09-05-2023, 02:44 PM.

              Comment


              • #52
                Originally posted by Pixel View Post

                It occurs to me that there may be an additional time savings because measuring a HIGH and a LOW may require an additional wasted cycle in-between.

                This way we just use the voltage to tell us whether a HIGH or LOW is next.
                I might be way off, but I'm reminded of Matsushita's 'MASH' technology here.

                Originally posted by Enzo
                I have a sign in my shop that says, "Never think up reasons not to check something."


                Comment


                • #53
                  Thinking about this while stuck in traffic today...even if you don't know what the voltage is, just doing the following will be an improvement. Worst case is you just started the HIGH pulse and have to wait almost a full cycle.

                  Halftime = pulseIn(guitar_in, HIGH, 20000UL) ; // read time​
                  frequency55 = 9091 / Halftime; // calculate frequency​

                  Comment


                  • #54
                    That's neat. I sometimes look at code and wonder how it does so much with so few lines. There's another way to speed processing up even more by using the interrupt pins and timers which eliminates timeout completely. I'm not sure at this stage though whether this would be necessary because at the moment I don't perceive any latency. Perhaps though if the functionality is increased at a later stage any blocking may become troublesome. The parts turned up yesterday to build a better fundamental extractor. After a lot of testing I'm convinced that the glitches are coming from the input side. I've got a few ideas to improve the signal conditioning that I need to breadboard, but it may also involve some coding changes depending on how it works out.

                    Comment


                    • #55
                      I built the OC-2 fundamental extractor and it's worse than my own design for this application. Whilst the output sounds perfectly good with the extractor output fed into an amp, the Arduino picks up any noise or signal aberrations and gives an unwanted output. The notes also have an unwanted modulation, with anything below A on the low E string being totally garbled like a random sample & hold patch. It's disappointing, because the PIC implementation of the OC-3 works fine. So a lot more to do on fundamental extraction and filtering.

                      Comment


                      • #56
                        After posting a request on Modwiggler to see if anyone knew how the original PIC signal processing worked precisely, I had an excellent series of replies from Synthiq. There's a lot more going on with that PIC16F88 than I expected and it's taken a while to learn enough about C++ to write something that has similar functionality. I had to give up on the previous quest to use high/low timing of a digital signal; there are just too many harmonics that complicate everything. I may come back to this, but for the time being have got a fairly decent system running using a 12ms fixed sample duration and level triggering to sample the frequency. It also struck me that accuracy in pitch detection isn't required. Once that had sunk in I was able to use arrays to get the DAC value. The overall accuracy comes from looking up the correct DAC entry for the note played. Anything within a half semitone either side of the desired note will always play the correct one, so if the frequency detection isn't perfect is never matters.

                        Also, all the calculations are now uint8_t or int and the prescaler on the ADC is set to run at 1MHz .

                        The downside is that there's no expression - the fretboard effectively becomes a keyboard, though this is more than made up for in the range of sounds that can be achieved. I'm working on hammer-ons and slides, but that's early days.

                        I have two versions of the code;
                        V1.0 has the same timing events as the original PIC code. It works way faster though and most of the latency has gone - just a little on the lower notes but isn't a problem.
                        V2.0 still samples the signal for 12ms, but then calculates the position and direction of the signal and this makes it faster still. The downside is it's more glitchy. I think this is because V1.0 detects trigger levels only on the rising edge, whereas V2.0 uses both the rising and falling edges and may be more prone to picking up harmonics.

                        I have this built up into a permanent install in my modular. It would be good to understand how this could be spliced into an Arduino synth MIDI sketch to give direct guitar control and PWM output to eliminate the DAC. That would make a nice stompbox-sized micro guitar synth that also has CV, trigger and Gate outputs. I did some sizing trials and removing the MIDI sections of the Helios One synth and adding the V1.0 code uses about 58% when compiled, so should run just fine and give additional space for a second oscillator.

                        Here's the schematic and code;
                        Click image for larger version  Name:	Guitar_to_CV V1.1.jpg Views:	0 Size:	324.8 KB ID:	991357

                        V1.0
                        Guitar_to_CV_Release_v1.0.ino.txt
                        V2.0
                        Guitar_to_CV_Release_v2.0.ino.txt
                        Attached Files
                        Last edited by Mick Bailey; 12-27-2023, 04:52 PM. Reason: EDIT: Schematic replaced with improved version that eliminates the 5V regulator circuit. Also, Arduino pin numbering corrected.

                        Comment


                        • #57
                          Here's a quick and hasty demo;
                          http://https://youtu.be/nA1bWnuWTjQ

                          Comment


                          • #58
                            Originally posted by Mick Bailey View Post
                            Here's a quick and hasty demo;
                            http://https://youtu.be/nA1bWnuWTjQ

                            Very cool!
                            That link doesn't work but here it is:

                            Originally posted by Enzo
                            I have a sign in my shop that says, "Never think up reasons not to check something."


                            Comment

                            Working...
                            X