User avatar
Magikbat
Posts: 3
Joined: Wed Jun 12, 2019 9:29 am

A problem with execution frequency

Thu Jun 13, 2019 10:31 am

Good morning, I'm Magikbat, new member of this forum. I come to ask for help with a project which I'm doing with my Raspberry Pi 3 Model B. It is about a EVSE (Electric Vehicle Supply Equipment) with J1772 standard. My programming level is basic so if you see some stupid mistake I'm willing to learn.

My system is composed of a L298 (H-bridge to generate de square wave signal for the J1772) and a ADS1115 (an ADC to read the high level of the square wave signal).

My problem start when I execute the code and I don't get a frequency of 1 kHz for the square wave signal. This is due to the fact that the part of the code that is constantly running I have verified that it takes much longer to execute than I need, especially in the conditioning part (about 0.05s, when I need that the entire program should be done in 0.001s).

Am I looking for something impossible with my project? Do you have any idea of what I'm failing? Is it a lack of code optimization? Could I do it better in another way?

Here I leave the code explained as best as possible:

Code: Select all

import RPi.GPIO as GPIO
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
from time import *

# GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
# LED/RELE
LED=22
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, False)
# Permiso APP
APP=23
GPIO.setup(APP, GPIO.OUT)
GPIO.output(APP, False)
# Motor A
INA_1=17
INA_2=18
GPIO.setup(INA_1, GPIO.OUT)
GPIO.setup(INA_2, GPIO.OUT)
GPIO.output(INA_1, False)
GPIO.output(INA_2, False)

# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
# Create the ADC object using the I2C bus
ads = ADS.ADS1115(i2c)
# Create single-ended input on channel 0
chan = AnalogIn(ads, ADS.P0)

# Here it is my problem
try:
    while True:
        GPIO.output(INA_1, True) #I put up the square wave signal with the H-bridge
        
        if float(chan.voltage) > 3.58: #My ADC doesn't read +4V, so I've scaled the values
            GPIO.output(LED, False)
            print(">>>>> STATE_A - Not Connected <<<<<")
            
        else:
            if (2.56 < float(chan.voltage) <=  3.58):
                GPIO.output(LED, False)
                print(">>>>> STATE_B - EV Connected (Ready) <<<<<")
            elif (1.54 < float(chan.voltage) <=  2.56) and (GPIO.input(APP)==True):
                GPIO.output(LED, True)
                print(">>>>> STATE_C - EV Charge <<<<<")
            elif (0.51 < float(chan.voltage) <=  1.54) and (GPIO.input(APP)==True):
                GPIO.output(LED, True)
                print(">>>>> STATE_D - EV Charge (Vent. Req.) <<<<<")
            else:
                GPIO.output(LED, False)
                print(">>>>> STATE_E - ERROR <<<<<")

            sleep(0.0002) #This sleep keeps the signal that I put on high 25% of the time of the frequency that I need to control the amperage through the duty cycle)
            GPIO.output(INA_1, False)
            GPIO.output(INA_2, True) #I put the square wave signal at -12V using the H-Bridge
            sleep(0.0008) #I keep the signal at -12V the rest of the time for my 1 kHz frequency
            GPIO.output(INA_2, False)
            GPIO.output(INA_1, True)

# CTRL+C to stop
except KeyboardInterrupt:
    GPIO.output(INA_1, False)
    GPIO.output(INA_2, False)
    GPIO.output(LED, False)
    GPIO.output(APP, False)
    pass
señal.stop()
GPIO.cleanup()
Thanks for your time.

User avatar
joan
Posts: 14075
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: A problem with execution frequency

Thu Jun 13, 2019 10:55 am

How accurate does the frequency need to be?

You need to adjust the sleep time to account for all the delays in the code (including the sleep itself). Change it until you get an average of a kHz.

If that is not good enough you will need to use a hardware PWM pin or something like (my) pigpio which can generate hardware timed PWM.

User avatar
Magikbat
Posts: 3
Joined: Wed Jun 12, 2019 9:29 am

Re: A problem with execution frequency

Fri Jun 14, 2019 9:44 am

joan wrote:
Thu Jun 13, 2019 10:55 am
How accurate does the frequency need to be?
1 kHz, as accurate as possible. This is how the J1772 standard works.
You need to adjust the sleep time to account for all the delays in the code (including the sleep itself). Change it until you get an average of a kHz.
Yes, I know it, but my main problem is that only this part takes about 0.05s (I checked it with code) when everything has to take 0.001s so I supposed that my problem is that the conditions takes a lot of time of execution. I put the code in the way that I checked the execution times:

Code: Select all

	GPIO.output(INA_1, True)
        if float(chan.voltage) > 3.58:
            GPIO.output(LED, False)
            print(">>>>> STATE_A - Not Connected <<<<<")
        else:
            start_time = time()
            if (2.56 < float(chan.voltage) <=  3.58):
                GPIO.output(LED, False)
                print(">>>>> STATE_B - EV Connected (Ready) <<<<<")
            elif (1.54 < float(chan.voltage) <=  2.56) and (GPIO.input(APP)==True):
                GPIO.output(LED, True)
                print(">>>>> STATE_C - EV Charge <<<<<")
            elif (0.51 < float(chan.voltage) <=  1.54) and (GPIO.input(APP)==True):
                GPIO.output(LED, True)
                print(">>>>> STATE_D - EV Charge (Vent. Req.) <<<<<")
            else:
                GPIO.output(LED, False)
                print(">>>>> STATE_E - ERROR <<<<<")
            elapsed_time = time() - start_time
            print("Elapsed time: ", elapsed_time, " seconds.")
If that is not good enough you will need to use a hardware PWM pin or something like (my) pigpio which can generate hardware timed PWM.
Could you explain in more detail?

Thank you.

hippy
Posts: 5582
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: A problem with execution frequency

Fri Jun 14, 2019 10:52 am

Magikbat wrote:
Fri Jun 14, 2019 9:44 am
Could you explain in more detail?
I am somewhat surprised that anyone who is dabbling with SAE J1772 is doing so without local resources to call upon, that you are not aware of hardware PWM and the problems inherent in bit-banging PWM, especially on a multi-tasking system.

I can see the appeal of bit-banged PWM as you are reading the voltage of the produced output and it allows easy synchronisation of ADC reading with pulse output. I would suggest off-loading the PWM and ADC reading to a simple microcontroller.
Last edited by hippy on Fri Jun 14, 2019 10:53 am, edited 1 time in total.

User avatar
joan
Posts: 14075
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: A problem with execution frequency

Fri Jun 14, 2019 10:53 am

An example using any spare GPIO. This uses a command line utility called pigs. You can do the same with pigpio Python calls.

sudo pigpiod # start the pigpio daemon

pigs pfs 4 1000 # set GPIO 4 to use a frequency of 1000

pigs p 4 128 # set GPIO 4 to use a dutycycle of 128 (out of 255).

http://abyz.me.uk/rpi/pigpio/pigs.html#PFS
http://abyz.me.uk/rpi/pigpio/pigs.html#P/PWM

Return to “Python”