Maker Pro
Maker Pro

8-Pin Development Board

chopnhack

Apr 28, 2014
1,576
Joined
Apr 28, 2014
Messages
1,576
I wasn't impressed with his delivery.
He is a bit slow and redundant - sometimes that is good to reinforce a point, other times it bores me to pieces. I sped the video up 25% and it was far more appreciable. More like some lectures at college where you are racing to keep up. I recall having to buy a cassette recorder for one professor because they zipped through material at warp speed... lots of extra time spent in recital and re-recital at home! :eek:

but I would view the course on-line first.
This was just an introductory module, one of I assume about 11 more as there are ten hours in the first volume. This was the only one offered free on youtube,

Just because a person is knowledgeable in a subject doesn't mean they are a great teacher.
QFT!

And even the best teachers sometimes make ill-advised remarks.
Agreed, he states at the beginning that he is trying to make this accessible to all - his example being a purely resistive circuit follows ohm's laws and a much greater current will run through the lower path of resistance - not supernatural, just mathematical ;)

This morning was quite productive, I read and understood most of pages 43-46 of the datasheet for the PIC12f675. All this multiplexing of a pin starting to make sense. One of the lessons I took on edX - the computing in your smartphone or something of that title had a whole section devoted to logic gates, building up from a transistor as one gate to more complicating gates like mux's - I looked at the datasheet, saw the diagram below and instantly got it!

The trapezoid on the left is the mux, mixing the four pins (multiplexed pins) and the channel select (hence CHS) is below - this is what we choose in the config. bits. Vref is tied internally so we can save a pin and use Vdd as our vref (hooray multiplexed pins!!) The ADC is similar in drawing to a comparator, input on left is 'compared' (used very loosely, Hop:D) to Vref coming in on top, ground below is controlled by A/D on switch, which is a transistor that allows ground to connect. Output on right gives us ten bits (1024 subdivisions of 5v or whatever Vref in was) to use in our programming.

I read over the TAD bit and didn't get as clear of a picture as I would have liked to, but ultimately for now I know that it is time of A/D cycle (I think) and I can simply use the internal RC oscillator - 4μs is plenty fast enough for tooling around.

upload_2016-6-3_10-39-50.png

What I am not sure of as of yet is the difference in Left vs Right justified data in the ADFM. It seems to show that the entire 10 bits is carried between the two registers and I can only surmise that this is done for the ease of the programmer? Are there other reasons for this? Have I missed the purpose of this bit?

upload_2016-6-3_10-49-34.png

Off to try my hand at some C for that pot sitting at AN0 err... AN1!
 

hevans1944

Hop - AC8NS
Jun 21, 2012
4,889
Joined
Jun 21, 2012
Messages
4,889
The ADC is similar in drawing to a comparator
Indeed it is. This particular ADC uses ten successive approximations to arrive at a 10-bit result. Details of how that is done are not revealed in the Microchip datasheet. Typically during each conversion the input voltage, stored on a sampling capacitor, is compared with a binary-attenuated Vref using a high-speed comparator. As the result of the comparison, a binary attenuator bit is set or cleared. Then the comparison is performed again and another, less significant, bit in the result is set or cleared. The process continues, bit-by-bit from the MSB to the LSB.

The only thing you need to know is it takes time to do those comparisons and change the attenuator bits for each successive approximation. Your software must allow for that time to pass. The conversion speed depends on the device clock speed, but there are setup time limitations on how fast the A/D can operate, and time limitations on how slow the A/D can operate before internal leakage currents change the charge stored on the sampling capacitor. The sampling capacitor must hold the sampled voltage to a variation of no more than one half the value of the least significant bit during the time it requires to complete the conversion. So A/D conversions are typically 1.6 to 6.4 μs, depending on processor clock speed and the division factor used for A/D clocking.

I can only surmise that this is done for the ease of the programmer? Are there other reasons for this? Have I missed the purpose of this bit?
There are many applications where you only need eight bits of resolution, so left-justifying makes those available at a single memory location. There may be other applications where only the least significant bits are of interest, so right-justification makes those available at a single memory location. So, yes, the two options are for the convenience of the programmer. There are even applications where only the two MSBs are of interest: autoranging circuits for example using an external programmable attenuator. Lots of reasons to pick one over the other. I would use left justification to "read" your potentiometer and ignore the two LSBs most of the time.

Using internal Vdd for Vref frees up a pin, but in some situations, such as reading a transducer whose output is a function of excitation voltage, such as a strain gauge bridge, it is desirable that Vref be derived from the transducer excitation voltage.

Most folks using the A/D function for the first time program the PIC to vary the duty cycle or the flashing rate of an LED as a function of potentiometer output voltage. Well, at least that is what was recommended to me when I started using the Arduino Uno. Should be applicable to PICs as well.

Let us know if you get it working. You are making outstanding progress in this hobby, BTW. :D
 

chopnhack

Apr 28, 2014
1,576
Joined
Apr 28, 2014
Messages
1,576
Most folks using the A/D function for the first time program the PIC to vary the duty cycle or the flashing rate of an LED as a function of potentiometer output voltage. Well, at least that is what was recommended to me when I started using the Arduino Uno. Should be applicable to PICs as well.

Oh, yes - well, I will not be conformist in that respect. I already know what I want to do with my ADC ;) - I will keep it simple at first until I get my head around it. I am almost tempted to try it in ASM after spending a few fruitless hours in C.... that's a change, LOL. Most of it is because of the obscurity of the labels for the pic pin outs! For instance, I simply want to take the value of ADRESH and put it into a variable so that I can compare that variable in an expression and take action on the result. For some reason I am getting unexpected token errors, even though I predefined the variable... pardon the code, it was a kludge to see if the ADC would function.
In my desperation, I have resorted to downloading a free trial version of Flowcode - I know, cop out :rolleyes::p - but I want to keep the momentum going ;)

Code:
unsigned int ADC_Read(unsigned char channel)
{
  if(channel > 3) //If Invalid channel selected 
    return 0;     //Return 0

  ADCON0 = 0b0000111;           //AD on, start, channel AN1
  __delay_ms(2);                //Acquisition time to charge hold capacitor
  GO_nDONE = 1;                 //Initializes A/D Conversion
  while(GO_nDONE);              //Wait for A/D Conversion to complete
  return ((ADRESH<<8)+ADRESL);  //Returns Result
}
   
    while(ADCON0bits.GO);         // wait for the conversion to finish
        val = ADC_Read(1);
        if val > 500
                GPIO = 0b000100;
            else    
                GPIO = 0b100000;                  
        __delay_ms(255); 
        __delay_ms(255);
}
       
            return;


Let us know if you get it working. You are making outstanding progress in this hobby, BTW. :D
Thanks mate! I am trying, the physics/math behind it is daunting for one to teach themselves, whereas the ideas are simple enough to understand. It's quite beautiful when you give it time to reflect on it. Thanks for your patience and support! :D:D
 

hevans1944

Hop - AC8NS
Jun 21, 2012
4,889
Joined
Jun 21, 2012
Messages
4,889
return ((ADRESH<<8)+ADRESL); //Returns Result
Why are you left-shifting ADRESH by eight bit positions before adding it to ADRESL? The two MSBs of ADRESL contain the LSBs of the result since ADFM = 0. Shouldn't you right-shift ADRESL by six bit positions and then concatenate it to ADRESH? Excuse me if my questions doesn't make sense... I don't do C much.
 

chopnhack

Apr 28, 2014
1,576
Joined
Apr 28, 2014
Messages
1,576
Why are you left-shifting ADRESH by eight bit positions before adding it to ADRESL?
That's part of the kludge - it's some code from the net that I was trying to follow along with to get this up and running. It was from a different chip set - had three ports etc. I haven't been able to clean it up much because I didn't understand why they were shifting the bits. This is not the only example of someone using the << operator - I saw it somewhere else as well.

Shouldn't you right-shift ADRESL by six bit positions and then concatenate it to ADRESH? Excuse me if my questions doesn't make sense... I don't do C much.
I will settle for just being able to get the contents of ADRESH into another variable that I can call and do ops on. I think I should stop this thread and start a new one on programming.
Do you think it would be easier with ASM?
 

hevans1944

Hop - AC8NS
Jun 21, 2012
4,889
Joined
Jun 21, 2012
Messages
4,889
Do you think it would be easier with ASM?
Well, maybe. But the code you wrote seems simple enough, although perhaps with some syntax errors... I don't see a main program loop, and the curly brackets "{ ... }" do not appear to be paired correctly... a left curly bracket is missing. And the whole code snippet appears to be a subroutine since it ends in "return" without any sign of a caller.

I would forget about using ADRESL and read ADRESH into variable "val" for comparison with the constant "500". That should at least allow you control a port, although I don't understand what
Code:
if val > 500
  GPIO = 0b000100;
else
  GPIO = 0b100000;
does. I guess we will continue this in your new thread... I can't help you with the C programming (or ASM for that matter) until I get the workbench set up in the basement this weekend.
 

chopnhack

Apr 28, 2014
1,576
Joined
Apr 28, 2014
Messages
1,576
Well, maybe. But the code you wrote seems simple enough, although perhaps with some syntax errors... I don't see a main program loop, and the curly brackets "{ ... }" do not appear to be paired correctly... a left curly bracket is missing. And the whole code snippet appears to be a subroutine since it ends in "return" without any sign of a caller.

I would forget about using ADRESL and read ADRESH into variable "val" for comparison with the constant "500". That should at least allow you control a port, although I don't understand what

does. I guess we will continue this in your new thread... I can't help you with the C programming (or ASM for that matter) until I get the workbench set up in the basement this weekend.

Or perhaps not until next week if that board makes it in tomorrow ;)
 
Top