Bus can Setup
CAN
Module Raspberry Pi
NT
22(GPIO25)
SCK
23 (SCK)
SI
19(MOSI)
S0
21 (MISO)
CS
24(CE0)
GND
(GND)
VCC
(3.3V)
Lancer les commandes suivantes :
sudo apt-get install can-utils
pip3 install python-can
sudo nano /boot/firmware/config.txt
Rajouter ce code :
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25
dtoverlay=sp1-1cs
Ensuite cliquer sur ctrl+x puis cliquer sur y puis entrer.
Redémarrer votre carte Raspberry
Après ça lancer cette commande :
sudo ip link set can0 up type can bitrate 500000
Pour envoyer une trame utilisant la commande suivante :
cansend can0 127#DEADBEEF
Pour recevoir lancer la commande suivante :
candump can0
Voici les lignes de code importantes qui serviront de base pour
élaborer un projet maître-esclave avec le protocole CAN sur des
Raspberry Pi :
Instruction pour le bus can
Initialisation du CAN (commun maître et esclave)
1. Importer les bibliothèques nécessaires :
import can
import RPi.GPIO as GPIO
import time
2. Configurer le bus CAN :
bus = can.interface.Bus(channel='can0', bustype='socketcan')
3. Créer une trame CAN :
message = can.Message(arbitration_id=0x101, data=[0x01, 0x02,
0x03], is_extended_id=False)
4. Envoyer une trame :
bus.send(message)
print(f"Message
sent:
Data={message.data}")
ID={hex(message.arbitration_id)},
5. Recevoir une trame :
msg = bus.recv()
if msg:
print(f"Message
Data={msg.data}")
received:
ID={hex(msg.arbitration_id)},
Pour le maître :
1. Envoyer une requête à un esclave :
request
=
can.Message(arbitration_id=0x105,
is_remote_frame=True, is_extended_id=False)
bus.send(request)
print(f"Request sent to ID={hex(request.arbitration_id)}")
2. Configurer les boutons GPIO :
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
sur le GPIO 17
# Bouton
3. Actionner un bouton pour envoyer une requête :
if GPIO.input(17) == GPIO.LOW:
# Si le bouton est pressé
bus.send(can.Message(arbitration_id=0x105,
is_remote_frame=True))
print("Request sent to slave with ID 0x105")
4. Analyser les réponses :
response = bus.recv()
if response and response.arbitration_id == 0x105:
print(f"Data received from slave: {response.data}")
Pour l'esclave :
1. Écouter les messages CAN :
while True:
msg = bus.recv()
if msg and msg.arbitration_id == 0x105:
print("Request received from master")
2. Répondre à une requête :
response = can.Message(arbitration_id=0x105,
0x20], is_extended_id=False)
data=[0x10,
bus.send(response)
print(f"Response sent: {response.data}")
3. Allumer une LED :
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.HIGH)
# LED connectée au GPIO 18
# Allumer la LED
time.sleep(5)
secondes
GPIO.output(18, GPIO.LOW)
# Maintenir allumée pendant 5
# Éteindre la LED
4. Actionner un servo-moteur :
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)
# Servo sur GPIO 23
pwm = GPIO.PWM(23, 50)
# Fréquence de 50 Hz
pwm.start(7.5)
# Position neutre
pwm.ChangeDutyCycle(5)
# Tourner le servo
time.sleep(1)
pwm.stop()
GPIO.cleanup()
Trames CAN pour un projet maître-esclave :
1. Requête du maître à un esclave :
can.Message(arbitration_id=0x101,
is_extended_id=False)
is_remote_frame=True,
2. Réponse de l'esclave avec des données :
can.Message(arbitration_id=0x101,
is_extended_id=False)
data=[0x12,
0x34],
3. Commande du maître pour une action (par exemple, allumer
une LED) :
can.Message(arbitration_id=0x107,
is_extended_id=False) # 0x01 pour allumer
data=[0x01],
4. Commande du maître pour contrôler un servo-moteur :
can.Message(arbitration_id=0x105,
data=[0x02],
is_extended_id=False) # 0x02 pour activer le servo
Résumé des lignes essentielles :
Fonctionnalité
Code important
Initialisation
du CAN
bus
=
can.interface.Bus(channel='can0',
bustype='socketcan')
Envoi de trame
bus.send(can.Message(arbitration_id=0x101,
data=[0x01, 0x02], is_extended_id=False))
Réception
trame
de msg = bus.recv()
Configuration
GPIO
GPIO.setmode(GPIO.BCM)
GPIO.OUT)
/
GPIO.setup(pin,
Actionner
LED
une GPIO.output(pin, GPIO.HIGH)
Activer
un pwm
=
GPIO.PWM(pin,
servo-moteur
pwm.ChangeDutyCycle(value)
Envoyer
requête
frequency)
/
une bus.send(can.Message(arbitration_id=0x105,
is_remote_frame=True))
Code d’envoi une trame
import can
def send_can_frame():
# Initialize the CAN bus
bus
=
bustype='socketcan')
can.interface.Bus(channel='can0',
# Create the CAN message
message = can.Message(arbitration_id=0x123,
0x22], is_extended_id=False)
# Send the message
try:
bus.send(message)
print(f"Message sent: {message}")
except can.CanError:
print("Error sending message")
if __name__ == "__main__":
send_can_frame()
data=[0x11,
Code de réception d’une trame
import can
def receive_can_message():
bus
=
bustype='socketcan')
can.interface.Bus(channel='can0',
while True:
msg = bus.recv()
if msg:
print(f"Message
reçu
ID={hex(msg.arbitration_id)}, Données={msg.data}")
:
print([f"{byte:02X}" for byte in msg.data])
if __name__ == "__main__":
receive_can_message()
import RPi.GPIO as GPIO
import can
import time
# CAN configuration
can_interface = 'can0'
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
# GPIO pin configuration for buttons
button_pins = [17, 18, 27, 22, 23, 24, 25]
buttons
# GPIO pins for
target_ids = [0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107]
# Corresponding CAN IDs
def send_can_request(target_id):
"""
Sends a CAN request to a specific target ID.
"""
try:
message
=
can.Message(arbitration_id=target_id,
is_extended_id=False, data=[0x01])
bus.send(message)
print(f"CAN request sent to ID {hex(target_id)}")
except can.CanError as e:
print(f"Failed
{hex(target_id)}: {e}")
to
send
CAN
request
to
ID
def button_callback(channel):
"""
Callback function triggered when a button is pressed.
"""
try:
index = button_pins.index(channel)
was pressed
target_id = target_ids[index]
# Find which button
# Get the corresponding
CAN ID
send_can_request(target_id)
except ValueError:
print(f"Unknown button pressed on GPIO {channel}")
if __name__ == "__main__":
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(button_pins,
pull_up_down=GPIO.PUD_DOWN)
GPIO.IN,
# Add event detection for button presses
for pin in button_pins:
GPIO.add_event_detect(pin,
callback=button_callback, bouncetime=300)
print("Master
request.")
is
ready.
Press
a
button
GPIO.RISING,
to
send
a
CAN
try:
while True:
time.sleep(1)
# Keep the script running
except KeyboardInterrupt:
print("Exiting...")
finally:
GPIO.cleanup()
# Reset GPIO pins on exit
import RPi.GPIO as GPIO
import can
import time
# Configuration de l'ID CAN de cet esclave
SLAVE_ID = 0x101
# Remplacez par l'ID CAN de cet esclave
# Configuration de la broche GPIO pour la LED
LED_PIN = 17
# Broche GPIO pour la LED (modifiez si nécessaire)
# Configuration de la broche GPIO pour la LED
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
# Éteindre la LED au démarrage
GPIO.output(LED_PIN, GPIO.LOW)
# Configuration du bus CAN
can_interface = 'can0'
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
def listen_for_requests():
"""
Écoute les requêtes CAN et effectue une action si l'ID
correspond.
"""
try:
print(f"Listening
{hex(SLAVE_ID)}...")
for
CAN
messages
on
ID
while True:
message = bus.recv()
# Attendre un message CAN
if message:
print(f"Message
received:
ID={hex(message.arbitration_id)}, Data={message.data}")
# Vérifier si l'ID du message correspond à celui
de cet esclave
if message.arbitration_id == SLAVE_ID:
print("Valid request received. Turning on
the LED.")
GPIO.output(LED_PIN, GPIO.HIGH)
# Allumer
la LED
time.sleep(5)
#
Garder
la
LED
allumée
pendant 5 secondes
GPIO.output(LED_PIN, GPIO.LOW)
# Éteindre
la LED
print("LED turned off after 5 seconds.")
except KeyboardInterrupt:
print("Exiting...")
finally:
GPIO.cleanup()
if __name__ == "__main__":
listen_for_requests()
Exemple priorité
import can
import time
# Configuration du bus CAN
can_interface = 'can0'
# Interface CAN
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
# Fonction pour envoyer une trame CAN complète
def envoyer_trame_can():
arbitration_id = 0x100
0x100 pour ce Raspberry Pi)
# ID d'arbitration (ex:
is_remote_frame = False
Remote
# Ce n'est pas une trame
data = [0x01, 0x02, 0x03, 0x04]
bytes)
# Exemple de données (4
# Calculer la longueur des données (DLC)
dlc = len(data)
# Création de la trame CAN
message = can.Message(
arbitration_id=arbitration_id,
is_extended_id=False,
standard
# ID d'arbitration
# Utilisation d'un ID
is_remote_frame=is_remote_frame,# Définir si c'est une
trame Remote
dlc=dlc,
data=data
(bytearray)
)
# Envoi de la trame
# Data Length Code
# Données de la trame
bus.send(message)
print(f"Message envoyé: ID {hex(arbitration_id)}, DLC {dlc},
Data {data}, RTR {is_remote_frame}")
# Envoi de la trame avec ID 0x100
envoyer_trame_can()
Réception avec des led
import can
import RPi.GPIO as GPIO
import time
# Configuration des broches GPIO pour les LEDs
GPIO.setmode(GPIO.BCM)
led_pins = [17, 27, 22, 5, 6, 13, 19]
GPIO 17, 27, etc.
# LED sur les broches
for pin in led_pins:
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.LOW)
éteintes au début
# Assurez-vous que les LEDs sont
# Configuration du bus CAN
can_interface = 'can0'
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
# Fonction pour allumer une LED en fonction de l'ID de la trame
def allumer_led(id_message):
if id_message < len(led_pins):
GPIO.output(led_pins[id_message], GPIO.HIGH)
la LED pour l'ID spécifié
# Allumer
time.sleep(2) # Garder la LED allumée pendant 2 secondes
GPIO.output(led_pins[id_message], GPIO.LOW)
la LED après 2 secondes
# Éteindre
# Fonction pour écouter les messages CAN
def ecouter_can():
while True:
message = bus.recv()
# Attente du message
if message and not message.is_remote_frame:
print(f"Message
{hex(message.arbitration_id)}")
reçu:
ID
allumer_led(message.arbitration_id)
if __name__ == "__main__":
print("En attente de messages CAN...")
ecouter_can()
dht11
import time
import can
import Adafruit_DHT
# GPIO pin for the DHT11 sensor
DHT_SENSOR = Adafruit_DHT.DHT11
DHT_PIN = 4
# GPIO pin for the DHT11 data pin
# CAN bus configuration
can_interface = 'can0'
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
def listen_for_requests():
while True:
# Wait for a request from the master
message = bus.recv()
if
message
and
message.is_remote_frame
message.arbitration_id == 0x300: # ID for DHT11 request
and
print("Request received from master.")
# Read temperature and humidity
humidity,
temperature
Adafruit_DHT.read(DHT_SENSOR, DHT_PIN)
=
if temperature is not None:
print(f"Temperature: {temperature}°C, Humidity:
{humidity}%")
# Convert temperature and humidity to integer
representation
temp_int
temperature by 10
=
int(temperature
hum_int = int(humidity * 10)
*
10)
#
Scale
# Scale humidity
by 10
# Pack data into a CAN message (2 bytes for temp,
2 bytes for humidity)
response_data = [temp_int >> 8, temp_int & 0xFF,
hum_int >> 8, hum_int & 0xFF]
# Send the response to the master
response = can.Message(arbitration_id=0x200,
data=response_data, is_extended_id=False)
bus.send(response)
print(f"Response sent: {response_data}")
else:
print("Failed to read from DHT11 sensor.")
time.sleep(2)
if __name__ == "__main__":
listen_for_requests()
servo commande
et led commande
import time
import can
import RPi.GPIO as GPIO
# GPIO pins for controlling the servo and LED
SERVO_PIN = 17
# GPIO pin for the servo motor
LED_PIN = 27
# GPIO pin for the LED
# CAN bus configuration
can_interface = 'can0'
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
# Servo and LED setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(SERVO_PIN, GPIO.OUT)
servo = GPIO.PWM(SERVO_PIN, 50)
# 50 Hz frequency
servo.start(0)
GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.output(LED_PIN, GPIO.LOW)
def send_request_to_dht11():
# Send a remote request frame to the DHT11 slave
request
=
can.Message(arbitration_id=0x300,
is_extended_id=False, is_remote_frame=True)
bus.send(request)
print("Request sent to DHT11 slave.")
def listen_for_responses():
message = bus.recv(timeout=5)
to 5 seconds
# Wait for a response for up
if message and message.arbitration_id == 0x200:
print(f"Response received: {message.data}")
# Decode the temperature from the response
temp_raw = (message.data[0] << 8) | message.data[1]
temperature = temp_raw / 10.0
# Scale back to original
print(f"Decoded temperature: {temperature}°C")
# If temperature exceeds 20°C, send commands
if temperature > 20:
print("Temperature
commands...")
exceeds
20°C,
sending
# Command to turn the servo motor (ID 0x105)
servo_command = can.Message(arbitration_id=0x105,
data=[1], is_extended_id=False)
bus.send(servo_command)
print("Servo motor command sent.")
# Command to turn on the LED (ID 0x107)
led_command
=
can.Message(arbitration_id=0x107,
data=[1], is_extended_id=False)
bus.send(led_command)
print("LED command sent.")
# Wait for 5 seconds
time.sleep(5)
# Command to turn off the LED (ID 0x107)
led_off_command = can.Message(arbitration_id=0x107,
data=[0], is_extended_id=False)
bus.send(led_off_command)
print("LED turn off command sent.")
def main():
try:
while True:
send_request_to_dht11()
# Send a request to the
listen_for_responses()
# Listen for the slave's
DHT11 slave
response
time.sleep(10)
next request
# Wait 10 seconds before sending the
except KeyboardInterrupt:
servo.stop()
GPIO.cleanup()
print("Program terminated.")
if __name__ == "__main__":
main()
servo bus can
import can
import RPi.GPIO as GPIO
import time
# GPIO pin configuration for the servo motor
SERVO_PIN = 17
# Initialize GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(SERVO_PIN, GPIO.OUT)
# Configure PWM for the servo motor
servo = GPIO.PWM(SERVO_PIN, 50)
# 50 Hz frequency
servo.start(0)
# CAN bus configuration
can_interface = 'can0'
bus
=
bustype='socketcan')
can.interface.Bus(channel=can_interface,
def set_servo_angle(angle):
"""Set the servo motor to a specific angle."""
duty_cycle = 2 + (angle / 18)
# Convert angle to duty cycle
servo.ChangeDutyCycle(duty_cycle)
time.sleep(0.5)
servo.ChangeDutyCycle(0)
jitter
# Stop sending signal to avoid
def listen_for_commands():
"""Listen for CAN commands and control the servo motor."""
try:
while True:
message = bus.recv()
if message and message.arbitration_id == 0x105:
Listen for ID 0x105
#
print(f"Command received: {message.data}")
if message.data[0] == 1:
# Command to activate
the servo
print("Activating servo motor.")
set_servo_angle(90)
degrees
# Move servo to 90
elif
deactivate the servo
message.data[0]
==
0:
#
Command
to
print("Deactivating servo motor.")
set_servo_angle(0)
degrees
except KeyboardInterrupt:
print("Stopping the program.")
servo.stop()
GPIO.cleanup()
if __name__ == "__main__":
listen_for_commands()
#
Move
servo
to
0
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )