problem about teensy4.1and ak60-6'

# مرحبا أصدقائي

### 🛠️ **مشكلتي:**
**لا يتحرك محرك AK60-6 باستخدام Teensy 4.1 وCAN Bus**

أواجه مشكلة في تشغيل **محرك AK60-6** باستخدام **Teensy 4.1** و**جهاز الإرسال والاستقبال CAN SN65HVD230**.
لقد قمت سابقًا بتحميل الكود وتشغيل المحرك بنجاح باستخدام تطبيق الشركة المصنعة (**cubeMarstool_v1.32**)، لذا فإن المحرك يعمل بشكل جيد.

---

## 🔧 تفاصيل الاتصالات والرمز والإعدادات:

### **المكونات المستخدمة:**
- **لوحة التحكم:** Teensy 4.1
- **وحدة إرسال واستقبال CAN:** SN65HVD230
- **المحرك:** AK60-6
- **مصدر طاقة المحرك:** 24 فولت تيار مستمر (4 أمبير)

---

### **اتصالات Teensy 4.1 إلى SN65HVD230:**
- `3.3V` (من Teensy) → `VCC` (على SN65HVD230)
- `GND` (من Teensy) → `GND` (على SN65HVD230)
- `الدبوس 31` (Teensy TX) → `TXD` (على SN65HVD230)
- `الدبوس 30` (Teensy RX) → `RXD` (على SN65HVD230)
- `CANL` (من SN65HVD230) → `CANL` (على محرك AK60-6)
- **لا يتم عكس اتصالات CANH/CANL**

---

### **المقاومات النهائية:**
- يوجد **مقاومة 120 أوم** على نهاية CAN (على لوحة SN65HVD230 من الشركة المصنعة).

---

### **إعدادات المحرك والرمز:**
- **معرف المحرك:** تم ضبطه على `66` (عشري) باستخدام تطبيق cubeMarstool_v1.32.
في الكود، تم تعيينه على `0x42` (سداسي عشري).
- **معدل البود:** تم ضبطه على `500000 بت في الثانية (500 كيلوبت في الثانية)` في تطبيق المحرك،
وقد تم تعديل الكود ليتناسب باستخدام:
`can3.setBaudRate(500000);`
- **المكتبة المستخدمة:** `FlexCAN_T4` (مثبتة)
- **وضع التحكم:** يرسل الكود الأمر للدخول إلى وضع التحكم:
`0xFF FF FF FF FF FF FC`

---

## ❗ العدد الحالي:

- **المحرك لا يزال لا يتحرك**.
- لا تظهر أخطاء واضحة في **الشاشة التسلسلية**، لكن المحرك لا يستجيب لأوامر الحركة.

---

## 🙏 طلب:
يرجى المساعدة في تحديد سبب عدم استجابة المحرك.
سأرفق **الكود المستخدم** و **صور الاتصال**.
[الرمز=cpp]```cpp
#تضمين <FlexCAN_T4.h>

FlexCAN_T4<CAN3، RX_SIZE_256، TX_SIZE_16> can3؛

// تعريف الحدود للمحرك AK60-6 (حسب الصفحة 4)
const float P_MIN = -12.5f; // راد (-95.5 درجة)
const float P_MAX = 12.5f; // راد (95.5 درجة)
ثابت عائم V_MIN = -41.87f؛ // راد/ثانية
ثابت عائم V_MAX = 41.87f؛ // rad/s
ثابت عائم T_MIN = -9.0f؛ // Nm
ثابت عائم T_MAX = 9.0f؛ // Nm
ثابت عائم KP_MIN = 0.0f؛
ثابت عائم KP_MAX = 500.0f؛
ثابت عائم KD_MIN = 0.0f؛
ثابت عائم KD_MAX = 5.0f؛

// دالة تتحول من float إلى uint (حسب الصفحة 6)
uint16_t float_to_uint(float x، float x_min، float x_max، uint8_t بت) {
مدى التعويم = x_max - x_min؛
إزاحة عائمة = x_min؛
العودة (uint16_t)((x - الإزاحة) * ((float)((1 << bits) - 1) / span));
}

// دالة تجهيز أمر CAN فطره للمحرك (حسب الصفحة 5)
void pack_cmd(CAN_message_t &msg، float p_des، float v_des، float kp، float kd، float t_ff) {
// تطبيق الحدود على القيم
p_des = constrain(p_des, P_MIN, P_MAX);
v_des = constrain(v_des, V_MIN, V_MAX);
kp = مقيد(kp، KP_MIN، KP_MAX)؛
kd = مقيد(kd، KD_MIN، KD_MAX)؛
t_ff = مقيد(t_ff، T_MIN، T_MAX)؛

// تحويل القيم إلى سجل سليمة بشكل مؤكد
uint16_t p_int = float_to_uint(p_des، P_MIN، P_MAX، 16)؛
uint16_t v_int = float_to_uint(v_des, V_MIN, V_MAX, 12);
uint16_t kp_int = float_to_uint(kp، KP_MIN، KP_MAX، 12)؛
uint16_t kd_int = float_to_uint(kd، KD_MIN، KD_MAX، 12)؛
uint16_t t_int = float_to_uint(t_ff، T_MIN، T_MAX، 12)؛

// تعبئة أقراص الرسالة CAN
msg.buf[0] = p_int >> 8؛
msg.buf[1] = p_int & 0xFF؛
msg.buf[2] = v_int >> 4؛
msg.buf[3] = ((v_int & 0xF) << 4) | (kp_int >> 8)؛
msg.buf[4] = kp_int & 0xFF؛
msg.buf[5] = kd_int >> 4؛
msg.buf[6] = ((kd_int & 0xF) << 4) | (t_int >> 8)؛
msg.buf[7] = t_int & 0xFF؛
}

إعداد باطل () {
التسلسل.البداية(115200);
تأخير(1000)؛

// تهيئة CAN بسرعة 1 ميجابت في الثانية (غيّرها إذا كنت تستخدم 500 كيلوبت في الثانية)
يمكن3.البدء();
can3.setBaudRate(1000000); // غيّر إلى 500000 إذا لزم الأمر
can3.enableFIFO();
can3.enableFIFOInterrupt();

// إرسال أمر الدخول في وضع التحكم
CAN_message_t أدخل عنصر التحكم؛
بالنسبة إلى (uint8_t i = 0؛ i < 7؛ i++) أدخل control.buf = 0xFF؛
أدخل control.buf[7] = 0xFC؛
enter_control.id = 0x42; // محرك الهوية
can3.write(أدخل التحكم)؛

Serial.println("تم محرك تهيئة AK60-6");
}

حلقة فارغة () {
موضع الهدف الثابت = 0.0f؛
أمر CAN_message_t؛
cmd.id = 0x42; // محرك الهوية

// إرسال أمر موضعي (90 درجة = 1.57 راديان)
pack_cmd(cmd، هدف الموضع، 0.0f، 40.0f، 0.5f، 0.0f)؛
can3.write(cmd);

// تغيير الموضع بين 0 و 90 درجة
هدف الموضع = (هدف الموضع == 0.0f) ؟ 1.57f : 0.0f؛

تأخير (2000)؛ // انتظر 2 ثانية
}
```[/CODE]

**شكرًا لك!**
Screenshot_20250626-041345_Gallery.jpg
 
>>> Translation copy ...
# Hello friends

### 🛠️ **My problem:**
**AK60-6 engine not moving with Teensy 4.1 and CAN Bus**

I'm having trouble running **AK60-6** engine using **Teensy 4.1** and **CAN SN65HVD230 transceiver.
I previously loaded the code and successfully ran the engine using the manufacturer's app (**cubeMarstool_v1.32**), so the engine works fine.



--- ## Connection 🔧 details, code and settings:

### **Components used:**
- **Control Panel:** Teensy 4.1
- **CAN Transceiver:** SN65HVD230
- **Motor:** AK60-6
- **Motor Power Supply:** 24V DC (4A)

---

### **Teensy 4.1 to SN65HVD230:**
- '3.3V' (from Teensy) → 'VCC' (SN65HVD230)
- 'GND' (from Teensy) → 'GND' (on SN65HVD230)
- 'Pin 31' (Teensy TX) → 'TXD' (SN65HVD230)
- 'Pin 30' (Teensy RX) → 'RXD' (on SN65HVD230)
- 'CANL' (from SN65HVD230) → 'CANL' (on AK60-6 engine)
- **CANH/CANL connections**

are not reversed ---

### **Final resistors:**
- **120 ohms** impedance on the CAN end (on the manufacturer's SN65HVD230 panel).


---
### **Engine and Code Settings:**
- **Engine ID:** Set to '66' (decimal) using the cubeMarstool_v1.32 app.
In the code, it is set to '0x42' (hexadecimal).
- **Pod rate:** set to '500,000 bps (500 kbps)' in the engine application,
and the code has been modified to suit using:
'can3.setBaudRate(500000);'
- **Library used:** 'FlexCAN_T4' (installed)
- **Control mode:** The code sends the command to enter control mode:
'0xFF FF FF FC'


---
## Current ❗ Issue:

- **The engine is still not moving**.
- No obvious errors appear in the serial screen, but the engine does not respond to movement commands.


---
## 🙏 Request:
Please help determine why the engine is not responding.
I will attach the **code used** and **contact images**.
[symbol=cpp]''cpp
Code:
<FlexCAN_T4.H>

FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> can3;

limit definition for AK60-6 engine (by page 4)
const float P_MIN = -12.5f; Reply (-95.5°)
const float P_MAX=12.5f; Reply (95.5°)
floating constant V_MIN = -41.87f; Rad/S
floating constant V_MAX = 41.87f; Rad/S
floating constant T_MIN = -9.0f; Nm floating
constant T_MAX = 9.0f; Nm floating
constant KP_MIN = 0.0f;
floating constant KP_MAX = 500.0f;
floating constant KD_MIN = 0.0f;
floating constant KD_MAX = 5.0f;

function converts from float to uint (by page 6)
uint16_t float_to_uint(float x, float x_min, float x_max, uint8_t bits) { float
range = x_max - x_min;
floating offset = x_min;
return(uint16_t)((x - offset) * ((float)((1 << bits) - 1)/span)); <b182> } // Command processing function CAN instinct for the engine (by page 5)
void pack_cmd(CAN_message_t &msg, float p_des, float v_des, float kp, float kd, float t_ff) {
Apply limits to values
p_des = constrain(p_des, P_MIN, P_MAX);
v_des = constrain(v_des, V_MIN, V_MAX);
kp = restricted(kp, KP_MIN, KP_MAX);
cd = restricted(kd, KD_MIN, KD_MAX);
t_ff = restricted(t_ff, T_MIN,

T_MAX);

Convert values to a definitively intact record
uint16_t p_int = float_to_uint(p_des, P_MIN, P_MAX, 16);
uint16_t v_int = float_to_uint(v_des, V_MIN, V_MAX, 12);
uint16_t kp_int = float_to_uint(kp, KP_MIN, KP_MAX, 12);
uint16_t kd_int = float_to_uint(kd, KD_MIN, KD_MAX, 12);
uint16_t t_int = float_to_uint(t_ff, T_MIN, T_MAX, 12);

// Fill message disks CAN
msg.buf[0] = p_int >> 8;
msg.buf[1] = p_int&0xFF;
msg.buf[2] = v_int >>4;
msg.buf[3] = ((v_int&0xF) << 4) | (kp_int >> 8);
msg.buf[4] = kp_int&0xFF;
msg.buf[5] = kd_int >>4;
msg.buf[6] = ((kd_int & 0xF) << 4) | (t_int >> 8);
msg.buf[7] = t_int&0xFF;
}
void()
setting {
sequence.start(115200);
delay(1000);

Configure CAN at 1 Mbps (other if you use 500 kbps)
can3.start();
can3.setBaudRate(1000000); Change to 500000 if necessary
can3.enableFIFO();
can3.enableFIFOInterrupt( );

Send command to enter control
mode CAN_message_t Enter the control;
for (uint8_t i = 0; i < 7; i++) Enter control.buf = 0xFF;
Enter control.buf[7] = 0xFC; 
enter_control.id = 0x42; can3.write identity
engine(Enter control); 

Serial.println("AK60-6 engine initialization"); 

} null
loop() { fixed target
position = 0.0f;
CAN_message_t command; 
cmd.id = 0x42; identity

drive // Send positional command (90°=1.57 radian)
pack_cmd(cmd, position target, 0.0f, 40.0f, 0.5f, 0.0f); 
can3.write(cmd); 

 Change position between 0 and 90 degrees
Position target = (Position target == 0.0f)? 1.57f: 0.0f; 

Delay (2000); Wait 2 sec
}
''

**Thank you!**
 
>>> نسخة الترجمة ...
# مرحباً أصدقائي

### 🛠️ **مشكلتي:**
**محرك AK60-6 لا يتحرك مع Teensy 4.1 وCAN Bus**

أواجه مشكلة في تشغيل محرك **AK60-6** باستخدام **Teensy 4.1** وجهاز الإرسال والاستقبال **CAN SN65HVD230.
لقد قمت مسبقًا بتحميل الكود وتشغيل المحرك بنجاح باستخدام تطبيق الشركة المصنعة (**cubeMarstool_v1.32**)، لذلك يعمل المحرك بشكل جيد.



--- ## 🔧 تفاصيل الاتصال والرمز والإعدادات:

### **المكونات المستخدمة:**
- **لوحة التحكم:** Teensy 4.1
- **جهاز إرسال واستقبال CAN:** SN65HVD230
- **المحرك:** AK60-6
- **مصدر طاقة المحرك:** 24 فولت تيار مستمر (4 أمبير)

---

### **Teensy 4.1 إلى SN65HVD230:**
- '3.3 فولت' (من Teensy) → 'VCC' (SN65HVD230)
- 'GND' (من Teensy) → 'GND' (على SN65HVD230)
- 'الدبوس 31' (Teensy TX) → 'TXD' (SN65HVD230)
- 'الدبوس 30' (Teensy RX) → 'RXD' (على SN65HVD230)
- 'CANL' (من SN65HVD230) → 'CANL' (على محرك AK60-6)
- **اتصالات CANH/CANL**

لا يتم عكسها ---

### **المقاومات النهائية:**
- **120 أوم** معاوقة على نهاية CAN (على لوحة SN65HVD230 الخاصة بالشركة المصنعة).


---
### **إعدادات المحرك والرمز:**
- **معرف المحرك:** تم ضبطه على "66" (عشري) باستخدام تطبيق cubeMarstool_v1.32.
في الكود، تم تعيينه على '0x42' (سداسي عشري).
- **معدل Pod:** تم ضبطه على "500,000 بت في الثانية (500 كيلو بت في الثانية)" في تطبيق المحرك،
وقد تم تعديل الكود ليناسب استخدام:
'can3.setBaudRate(500000);'
- **المكتبة المستخدمة:** 'FlexCAN_T4' (مثبتة)
- **وضع التحكم:** يرسل الكود الأمر للدخول إلى وضع التحكم:
'0xFF FF FF FC'


---
## ❗ العدد الحالي:

- **المحرك لا يزال لا يتحرك**.
- لا تظهر أخطاء واضحة في الشاشة التسلسلية، لكن المحرك لا يستجيب لأوامر الحركة.


---
## 🙏 طلب:
يرجى المساعدة في تحديد سبب عدم استجابة المحرك.
سأقوم بإرفاق **الرمز المستخدم** و **صور الاتصال**.
[الرمز=cpp]''cpp
[الرمز]<FlexCAN_T4.H>

FlexCAN_T4<CAN3، RX_SIZE_256، TX_SIZE_16> can3؛

تعريف الحد الأقصى لمحرك AK60-6 (حسب الصفحة 4)
ثابت عائم P_MIN = -12.5f؛ رد (-95.5 درجة)
ثابت عائم P_MAX=12.5f؛ رد (95.5 درجة)
ثابت عائم V_MIN = -41.87f؛ Rad/S
الثابت العائم V_MAX = 41.87f؛ Rad/S
ثابت عائم T_MIN = -9.0f؛ نيوتن متر عائم
ثابت T_MAX = 9.0f؛ نيوتن متر عائم
الثابت KP_MIN = 0.0f؛
الثابت العائم KP_MAX = 500.0f؛
الثابت العائم KD_MIN = 0.0f؛
الثابت العائم KD_MAX = 5.0f؛

تقوم الدالة بالتحويل من float إلى uint (حسب الصفحة 6)
uint16_t float_to_uint(float x، float x_min، float x_max، uint8_t بت) { float
المدى = x_max - x_min؛
الإزاحة العائمة = x_min؛
return(uint16_t)((x - offset) * ((float)((1 << bits) - 1)/span)); <b182> } // وظيفة معالجة الأوامر CAN غريزة للمحرك (حسب الصفحة 5)
void pack_cmd(CAN_message_t &msg، float p_des، float v_des، float kp، float kd، float t_ff) {
تطبيق الحدود على القيم
p_des = constrain(p_des, P_MIN, P_MAX);
v_des = constrain(v_des, V_MIN, V_MAX);
kp = مقيد(kp، KP_MIN، KP_MAX)؛
cd = مقيد(kd، KD_MIN، KD_MAX)؛
t_ff = مقيد(t_ff، T_MIN،

T_MAX)؛

تحويل القيم إلى سجل سليم نهائيًا
uint16_t p_int = float_to_uint(p_des، P_MIN، P_MAX، 16)؛
uint16_t v_int = float_to_uint(v_des, V_MIN, V_MAX, 12);
uint16_t kp_int = float_to_uint(kp، KP_MIN، KP_MAX، 12)؛
uint16_t kd_int = float_to_uint(kd، KD_MIN، KD_MAX، 12)؛
uint16_t t_int = float_to_uint(t_ff، T_MIN، T_MAX، 12)؛

//ملء أقراص الرسائل CAN
msg.buf[0] = p_int >> 8؛
msg.buf[1] = p_int&0xFF؛
msg.buf[2] = v_int >>4؛
msg.buf[3] = ((v_int&0xF) << 4) | (kp_int >> 8)؛
msg.buf[4] = kp_int&0xFF؛
msg.buf[5] = kd_int >>4؛
msg.buf[6] = ((kd_int & 0xF) << 4) | (t_int >> 8)؛
msg.buf[7] = t_int&0xFF؛
}
فارغ()
جلسة {
التسلسل.بدء(115200);
تأخير(1000)؛

تكوين CAN بمعدل 1 ميجابت في الثانية (غير ذلك إذا كنت تستخدم 500 كيلوبت في الثانية)
can3.start();
can3.setBaudRate(1000000); قم بالتغيير إلى 500000 إذا لزم الأمر
can3.enableFIFO();
can3.enableFIFOInterrupt( );

إرسال أمر لإدخال التحكم
وضع CAN_message_t أدخل عنصر التحكم؛
بالنسبة إلى (uint8_t i = 0؛ i < 7؛ i++) أدخل control.buf = 0xFF؛
أدخل control.buf[7] = 0xFC؛
enter_control.id = 0x42؛ can3.write الهوية
المحرك(أدخل التحكم)؛

Serial.println("تهيئة محرك AK60-6");

} باطل
loop() { هدف ثابت
الموضع = 0.0f؛
أمر CAN_message_t؛
cmd.id = 0x42؛ الهوية

محرك الأقراص // إرسال أمر موضعي (90 درجة = 1.57 راديان)
pack_cmd(cmd، موضع الهدف، 0.0f، 40.0f، 0.5f، 0.0f)؛
can3.write(cmd);


تغيير الوضع بين 0 و 90 درجة
هدف الموضع = (هدف الموضع == 0.0f)؟ 1.57f: 0.0f؛

التأخير (2000)؛ انتظر لمدة ثانيتين
}
''[/شفرة]

**شكرًا لك!**
what
 
Back
Top