Author Topic: Write EEPROM By Pin Problem  (Read 4014 times)

0 Members and 4 Guests are viewing this topic.

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Write EEPROM By Pin Problem
« on: February 06, 2018, 07:58:15 am »
Hello all,

I'm working on a stepper motor controller program,  it all works great except this single issue I'm having.

As these stepper motors were not cabled identically,  the program does have a 'programming' sequence where the service tech' can set the motor direction (it only spins in one direction for its entire life) during the initial setup,  this would only be carried out once a decade or so. The idea is the uC can be started with a resistor held to pin RB3 if the direction needs changing,  the RB3 pin is disonnected from the ground plane of the PCB by virtue of being fitted in a socket with the pin cut off!

I am using the EEPROM elsewhere in the program and it works fine, so I'm happy with the read/write functions I've written,  I just can not get this programming to work. If I step through the program using the virtual pins in MPLAB it all works splendidly, but not in the real world:

Code: [Select]
//---------------Direction programming Prototype-----------//
//--------------Only to run during prime cycle------------//
void PROG_DIR (void){
    if (DIR == 1){  //Check for current configuration
        write_eeprom(0x01, 00);  //Write DIR value to 0 in EEPROM
        write_eeprom(0x00, 01); //Write USERCONFIG flag
                   
       
    }
    else {

        write_eeprom(0x01, 01);  //Write DIR value to 1 in EEPROM
        write_eeprom(0x00, 01); //Write USERCONFIG flag
    }
    DIR = EEread_b(0x01);  //Reload DIR value from EEPROM
       
}

//-----STARTUP PRIME Prototype------------------------------------------//
void prime (void)
{
    //Set up TIMER1//
    T1Count = 2;  //Load T1count
    T1CONbits.TMR1CS=0; //Derive Timer1 from FOSC
    T1CONbits.T1CKPS=01; //Use 1:4 Prescaler
    T1CONbits.TMR1ON=1; //Turn Timer1 On.
   
   //----//
    while (T1Count>2){ //Wait for Timer1 to reach 2
        pump (T1Count);
    }
    T0CONbits.TMR0ON=1; //Switch on Timer0
    //Check for programming pin HIGH status//
    TRISBbits.RB3 = 1; //Turn on RB3 Input
    if (PROG == 1){
        PROG_DIR();
    }
    TRISBbits.RB3=0; //Turn off RB3 Input
    //----//
    while (T0Count <5){  //Run fast prime for approx 50s
        pump(2); //Fast Prime Pump Speed
    }
    T0CONbits.TMR0ON=0; //Switch off Timer0
    T0Count=0; //Reset Timer0 Counter
    T1CONbits.TMR1ON=0; //Switch off Timer1
    T1Count=0; //Reset Timer1 Count
    }

The 'Prime' function calls the 'Prog' function if the pin is high,  if not it carries on.

Any suggestions what may be causing this not to work in practice?

Cheers,
Ed
 

Offline donotdespisethesnake

  • Super Contributor
  • ***
  • Posts: 1093
  • Country: gb
  • Embedded stuff
Re: Write EEPROM By Pin Problem
« Reply #1 on: February 06, 2018, 10:08:12 am »
Quote
The 'Prime' function calls the 'Prog' function if the pin is high,  if not it carries on.

Code: [Select]
   TRISBbits.RB3 = 1; //Turn on RB3 Input
    if (PROG == 1){
        PROG_DIR();
    }
    TRISBbits.RB3=0; //Turn off RB3 Input

Looks like PROG_DIR() is called if PROG is 1. I don't see where RB3 is read in? Is there relevant code you have not shown us?
Bob
"All you said is just a bunch of opinions."
 

Offline obiwanjacobi

  • Super Contributor
  • ***
  • Posts: 1030
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: Write EEPROM By Pin Problem
« Reply #2 on: February 06, 2018, 11:22:55 am »
So you have floating input pin?
Does it have a pull up or down enabled?
Wrong code should not compile!
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Write EEPROM By Pin Problem
« Reply #3 on: February 06, 2018, 03:53:29 pm »
Cheers all,

It's defined at the top of the program in:

Code: [Select]
#define _XTAL_FREQ 8000000  //Define XTAL ref for _delay function
#define PULSE LATAbits.LATA0 //RA0 Defined as PULSE pin
#define DIR LATAbits.LATA1 //RA1 Defined as DIRECTION pin
#define SPEED PORTBbits.RB0 //RB0 Defined as PRIME control pin
#define PROG PORTBbits.RB3 //RB3 Defined as Direction Programming Pin

I've also tried turning on the internal pull-up and using the value of zero (pin bridged to ground) but still nothing as:

Code: [Select]
void prime (void)
{
    //Set up TIMER1//
    T1Count = 2;  //Load T1count
    T1CONbits.TMR1CS=0; //Derive Timer1 from FOSC
    T1CONbits.T1CKPS=01; //Use 1:4 Prescaler
    T1CONbits.TMR1ON=1; //Turn Timer1 On.
   
   //----//
    while (T1Count>2){ //Wait for Timer1 to reach 2
        pump (T1Count);
    }
    T0CONbits.TMR0ON=1; //Switch on Timer0
    //Check for programming pin HIGH status//
    TRISBbits.RB3 = 1; //Turn on RB3 Input
    INTCON2bits.RBPU = 0; //Turn on PULL UP on PortB
    if (PROG == 0){
        PROG_DIR();
    }
    TRISBbits.RB3=0; //Turn off RB3 Input
    //----//
    while (T0Count <5){  //Run fast prime for approx 50s
        pump(2); //Fast Prime Pump Speed
    }
    T0CONbits.TMR0ON=0; //Switch off Timer0
    T0Count=0; //Reset Timer0 Counter
    T1CONbits.TMR1ON=0; //Switch off Timer1
    T1Count=0; //Reset Timer1 Count
    }
   

Still confused :(

Cheers,
Ed
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3921
  • Country: it
Re: Write EEPROM By Pin Problem
« Reply #4 on: February 06, 2018, 04:03:43 pm »
I'll never stop saying it: I don't like reading pins this way. Never found it reliable.
It SHOULD translate to single BTFSS/BTFSC or whatever instructions in 16/32 bit parts, but it never worked reliably for me.

Sample the port.
Test by masking the sampled port.
Much more reliable results.

Code: [Select]
uint8_t PORTB_sample;

[..]
PORTB_sample = PORTB;
if (!(PORTB_Sample & (1 << 3))) {
  //Same as if (PORTBbits.PORTB3 == 0)
  //! negates, so true if zero
  //1 << 3 because i find it easier than "8" to remember as "Bit 3"
}
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2340
Re: Write EEPROM By Pin Problem
« Reply #5 on: February 06, 2018, 04:08:07 pm »
DIR appears to be defined as the latched-bits. So you are reading the value that was last written to the port pin - which, at this stage of the program, appears to be undefined.
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3921
  • Country: it
Re: Write EEPROM By Pin Problem
« Reply #6 on: February 06, 2018, 04:44:27 pm »
as per his latest post he's reading "PROG" which is defined as PORTBbits.RB3. the value of PORTB is updated during the instruction cycle reflecting the state of the pin, regardless if it's an input,output, GP or controlled by a peripheral (unless it's programmed as Analog)
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2340
Re: Write EEPROM By Pin Problem
« Reply #7 on: February 06, 2018, 04:56:50 pm »
I agree that PROG is being used correctly, however, since prime appears to be part of an initialisation sequence, and we've not been shown any prior code, I was questioning the value of DIR - which (considering the posted code) appears to either be undefined, or read as input from RA1 - either way, it appears not to be defined until after it is used to toggle its state! Unless, of course, there is more code that we've not seen.

 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Write EEPROM By Pin Problem
« Reply #8 on: February 06, 2018, 06:26:45 pm »
Cheers all,  okay this is a bit of a weird one - I've written the software to load the EEPROM values in to the int values (sort of self programming) after checking to see if the user has redefined the standard values,  this is done here:

Code: [Select]
//------------Initialisation of EEPROM Prototype------//
void checkinit (void) {
    userprog = EEread_b (0x00);
    if (userprog != 1){
    write_eeprom (0x01, 1);  //Set DIR to '1'
    write_eeprom (0x02, 54);  //Set MEDTIME to '54' *********CRITICAL***********
    write_eeprom (0x00, 1); //Set Programming flag high.
    }
    else;  // If chip already configured by user,  escape prototype.
}

Code: [Select]
//-----------------READ IN Prototype--------------//
void read_in (void){
    DIR = EEread_b (0x01);
    MEDTIME = EEread_b (0x02);
   
}

It's called here at the top of the program, before the loop:

Code: [Select]
    checkinit();  //Check to see if user has configured chip
    read_in(); // Load in parameters from EEPROM
    /* startup_delay(); // Startup delay to compensate for power-on relay delay */
    prime();   // Run FAST-PRIME Prodecure
   

The delay has been commented out for my sanity whilst testing on the bench (it's a 60s delay, it's irritating whilst testing!)

I hope this thins,  (or indeed thickens) the plot,  as the program otherwise works flawlessly, it seems that pulling values in-and-out of the EEPROM and assigning them isn't an issue.

Cheers,
Ed


 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2452
  • Country: us
Re: Write EEPROM By Pin Problem
« Reply #9 on: February 06, 2018, 06:59:34 pm »
Try inserting a 1 ms delay between turning the pin on and reading it. My theory is you're reading the pin before the input is stable. If that's it, obviously 1 ms is way longer than needed, but it's fine for a first test.
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Write EEPROM By Pin Problem
« Reply #10 on: February 06, 2018, 07:12:12 pm »
1ms is absolutely fine, this isn't a timing critical application, the timers are near enough to about 15s!

It's for an industrial pump system in a non-critical/non-safety application,  this is just a refinement of the standard software to tidy up a few irritating things about the standard software.

I'll give it a try!

Cheers,
Ed
 

Online NorthGuy

  • Super Contributor
  • ***
  • Posts: 3579
  • Country: ca
Re: Write EEPROM By Pin Problem
« Reply #11 on: February 06, 2018, 07:41:53 pm »
I don't quite understand why you're doing this. If someone cuts off the pin, it is not going to grow back, right? So, you can simply read the state of the pin at the beginning every time such as:

Code: [Select]
DIR = PROG;
That's all you need (except configuring pins and enabling pull-ups).

This has an added advantage that if they do want to change the direction afterwards, they simply solder back the pin. It is much better for the people in the field than going through your complex "imprinting" procedure.

 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1068
Re: Write EEPROM By Pin Problem
« Reply #12 on: February 06, 2018, 08:06:35 pm »
Maybe I missed it, but which chip is this? It would probably help if it was known.

For example, you may have a chip where RB3 has an alternate use where its fused on to that alternate use, causing the digital in to read as 0.

just looking at previous posts, the OP may be using a PIC18F1330?
from datasheet-

On a Power-on Reset, PORTB is
configured as digital inputs except for RB2
and RB3.
RB2 and RB3 are configured as analog
inputs when the T1OSCMX bit of Configuration
Register 3H is cleared. Otherwise,
RB2 and RB3 are also configured as
digital inputs.
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Write EEPROM By Pin Problem
« Reply #13 on: February 06, 2018, 08:53:31 pm »
Maybe I missed it, but which chip is this? It would probably help if it was known.

For example, you may have a chip where RB3 has an alternate use where its fused on to that alternate use, causing the digital in to read as 0.

just looking at previous posts, the OP may be using a PIC18F1330?
from datasheet-

On a Power-on Reset, PORTB is
configured as digital inputs except for RB2
and RB3.
RB2 and RB3 are configured as analog
inputs when the T1OSCMX bit of Configuration
Register 3H is cleared. Otherwise,
RB2 and RB3 are also configured as
digital inputs.
Yes, sorry that was entirely my error, it's PIC18F1330, different application than last time though!

Interesting about the registers.

I think the part about cutting the pin might be a consideration!
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Write EEPROM By Pin Problem
« Reply #14 on: February 06, 2018, 09:07:08 pm »
I don't quite understand why you're doing this. If someone cuts off the pin, it is not going to grow back, right? So, you can simply read the state of the pin at the beginning every time such as:

Code: [Select]
DIR = PROG;
That's all you need (except configuring pins and enabling pull-ups).

This has an added advantage that if they do want to change the direction afterwards, they simply solder back the pin. It is much better for the people in the field than going through your complex "imprinting" procedure.
Sorry I don't think I explained the intention very well.

These control stepper motors which were not identically cabled,  some will spin CW with DIR pin high, some CCW.

The pump, for its entire life must only spin CW,  there is no need for it to spin CCW at all,  ever.

Now, obviously the sensible answer is to reverse a winding,  however this is a bit of a pig of a job on this machine, the terminals are 'well buried' so when the new uC is installed it's pretty much a 50/50 as to which way the motor will spin.

My thought (although I think I've coded it impossibly badly) was that the state of the direction pin (high or low) could be stored in EEPROM then adjusted during the start up cycle by simply physically holding a resistor to the programming pin and reversing the status of the direction pin until such a time the motor is changed or something else curious happens.   This can then be left alone for years at a time and merrily run in the correct direction.

The bit about 'cutting the pin off' wasn't explained well by myself:

This is using an existing board where RB3 was never utilised and was just held low,  I've installed the test uC's in a socket with the RB3 pin cut off (so the chip isn't damaged, just the socket) this breaks the connection between RB3 and ground that'd I'd have by just plugging the chip in.

You know, somehow, I think I've explained this in an even more complicated way!

Basically  tech' can as an installation job restart with a resistor held to RB3 if the motor spins backwards on power up,  DIR pin status is reversed,  life goes on....

Does that make any more sense, or am I making this more obtuse!

Cheers,
Ed
 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1068
Re: Write EEPROM By Pin Problem
« Reply #15 on: February 06, 2018, 09:26:19 pm »
simply double-check- T1OSCMX bit of Configuration Register 3H
two possibilities, and one of them would cause your problem
 

Online NorthGuy

  • Super Contributor
  • ***
  • Posts: 3579
  • Country: ca
Re: Write EEPROM By Pin Problem
« Reply #16 on: February 06, 2018, 09:32:11 pm »
I see. The logic you have is rather complex. As you describe, you only need to do the following (in pseudo-code):

Code: [Select]
DIR = READ_EEPEOM(ADDR_OF_DIR); // Is ready to spin the motor in some direction.
// The direction will be the same from statt to start because it is read from EEPROM
// Doesn't matter how it is initialized because we don't know the correct direction anyway

if (~PROG) {
  // Oops; someone holding the pin short, which means the motor would spin in the wrong direction.

  // Need to change the direction to the correct one
  DIR = ~DIR;

  // and remember this for future starts.
  WRITE_EEPROM(ADDR_OF_DIR,DIR);
}

It would be nice to have a push-button instead of holding a wire against the pin - not all people have good vision and steady hands.

Also. I wouldn't trust the built-in pull-up around the motors and install a stronger external one.

 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Write EEPROM By Pin Problem
« Reply #17 on: February 06, 2018, 09:38:54 pm »
Good point,  the register is HIGH in my pragmatic setup though.

@NorthGuy - yes, you can tell I'm a very green programmer can't you, I'm a touch 'verbose' at the moment,  I like to hack something together, then print out the code and physically start slashing away at it with a pencil until I can whittle it in to something that makes more sense, or at least a good deal more efficient!

Thank you all for your help, it truly is appreciated.
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2452
  • Country: us
Re: Write EEPROM By Pin Problem
« Reply #18 on: February 06, 2018, 10:17:01 pm »
Or, since there's only two possibilities, simply have a configuration switch/jumper pins/solder pads connected to that pin that the tech can permanently change. Then you wouldn't need to save the value in eeprom.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->