HobbyKing ESC und I2C Fragen
Hallo,
ich habe momentan keine Funke, und versuche trotzdem die Schaltung zu testen.
Ich habe die "Mini" version der Platine, mit den I2C->PWM convertern von Willi. Als ESC habe ich die Hobbyking SS Series 18-20A ESC (card programmable) http://www.hobbyking.com/hobbyking/s...idProduct=6548
Ich habe also den I2C->PWM converter an die Platine, und an den ESC angeschlossen, und den ESC an den Motor. Nun versuche ich mit I2C comandos den Motor anzusteuern, klappt aber nicht.
Die Ansteuerung mache ich mit einem kleinen Program, das ich über die Serielle schnittstelle mit den Komandos versorge z.B. ML=80 (soll den Wert 80 zum linken Motor senden. Unden habe ich den Code angführt.
Hat jemand Erfahrung mit den ESC, und/oder ein Beispielprogram wie ich die motor ansteuerung testen kann. Ich habe leider kein Oszi, und kann mir darum die signale nicht anschauen.
Danke Gerald
Code:
/*
* main.cpp
*
* Created on: Oct 5, 2010
* Author: geraldf
*/
#include <WProgram.h>
#include <Wire.h>
#include "SoftI2CMaster.h"
//--I2C--
const byte M_h = 0x52; //i2c address: motor at the back
const byte M_l = 0x54; //i2c address: motor at the left
const byte M_r = 0x56; //i2c address: motor at the right
const byte sdaPin = 4;
const byte sclPin = 5;
// LED Pins
int BackLED = 7;
int RightLED = 8;
int LeftLED = 9;
int ParseCommand(char *);
void I2CSend( int, int);
int BlinkLED(int );
extern "C" void __cxa_pure_virtual() {
}
int ledPin = 13; // LED connected to digital pin 13
int i = 0;
char str[255];
int inp;
char str1[] = "Test1";
// The setup() method runs once, when the sketch starts
void setup() {
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
pinMode (BackLED, OUTPUT);
pinMode (LeftLED, OUTPUT);
pinMode (RightLED, OUTPUT);
Serial.begin(9600);
Wire.begin();
Serial.println("Hello Master, I am online and waiting for your commands!");
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop() {
if (Serial.available() > 0 && i < 255) {
// read the incoming byte:
inp = Serial.read();
//digitalWrite(ledPin, HIGH); // set the LED on
//delay(500L); // wait for a second
//digitalWrite(ledPin, LOW); // set the LED off
//delay(500L); // wait for a second
// say what you got:
//Serial.print("I received: ");
//Serial.println(inp);
if (inp != 10) {
str[i++] = inp;
} else {
str[i] = '\0';
i = 0;
Serial.print("I received: ");
Serial.println(str);
if (ParseCommand(str) > 0) {
Serial.println("Invalid Command!");
}
}
}
}
int main(void) {
/* Must call init for arduino to work properly */
init();
setup();
for (;;) {
loop();
} // end for
} // end main
int ParseCommand(char* s) {
char cmd[255];
strcpy(cmd, s);
cmd[3] = '\0'; // command only (ML=, MR= or MH=)
if (strcmp(cmd, "ML=") == 0 || strcmp(cmd, "MR=") == 0
|| strcmp(cmd, "MH=") == 0) {
Serial.print("command ");
Serial.print(cmd);
Serial.println(" found!");
//parsing value now
int value = 0;
char v[5];
strcpy(v, s + 3);
Serial.print("value = ");
value = atoi(v);
Serial.println(value);
switch (cmd[1])
{
case 'H':
BlinkLED(1);
I2CSend(M_h,value);
break;
case 'L':
BlinkLED(2);
I2CSend(M_l,value);
break;
case 'R':
BlinkLED(4);
I2CSend(M_r,value);
break;
}
return (0);
}
else if (strcmp(s,"stop")== 0)
{
Serial.println("All Motors will stop!");
I2CSend(M_h,0);
I2CSend(M_l,0);
I2CSend(M_r,0);
BlinkLED(7);
return 0;
}
else
{
return (1);
}
return (0);
}
void I2CSend( int adr, int cmd)
{
// Wire.beginTransmission (adr);
// Wire.send(cmd);
// Wire.endTransmission();
SoftI2CMaster i2c = SoftI2CMaster( sdaPin,sclPin );
i2c.beginTransmission(adr);
i2c.send(cmd);
i2c.endTransmission();
}
int BlinkLED(int LED)
{
switch(LED)
{
case 1:
digitalWrite(BackLED, HIGH); // set the LED on
delay(100L);
break;
case 2:
digitalWrite(LeftLED, HIGH); // set the LED on
delay(100L);
break;
case 4:
digitalWrite(RightLED, HIGH); // set the LED on
delay(100L);
break;
case 3:
digitalWrite(BackLED, HIGH); // set the LED on
digitalWrite(LeftLED, HIGH); // set the LED on
delay(100L);
break;
case 7:
digitalWrite(BackLED, HIGH); // set the LED on
digitalWrite(LeftLED, HIGH); // set the LED on
digitalWrite(RightLED, HIGH); // set the LED on
delay(100L);
break;
}
digitalWrite(BackLED, LOW); // set the LED on
digitalWrite(LeftLED, LOW); // set the LED on
digitalWrite(RightLED, LOW); // set the LED on
return 0;
}
HobbyKing ESC und I2C Fragen
Hallo,
ich habe momentan keine Funke, und versuche trotzdem die Schaltung zu testen.
Ich habe die "Mini" version der Platine, mit den I2C->PWM convertern von Willi. Als ESC habe ich die Hobbyking SS Series 18-20A ESC (card programmable) http://www.hobbyking.com/hobbyking/s...idProduct=6548
Ich habe also den I2C->PWM converter an die Platine, und an den ESC angeschlossen, und den ESC an den Motor. Nun versuche ich mit I2C comandos den Motor anzusteuern, klappt aber nicht.
Die Ansteuerung mache ich mit einem kleinen Program, das ich über die Serielle schnittstelle mit den Komandos versorge z.B. ML=80 (soll den Wert 80 zum linken Motor senden. Unden habe ich den Code angführt.
Hat jemand Erfahrung mit den ESC, und/oder ein Beispielprogram wie ich die motor ansteuerung testen kann. Ich habe leider kein Oszi, und kann mir darum die signale nicht anschauen.
Danke Gerald
Code:
/*
* main.cpp
*
* Created on: Oct 5, 2010
* Author: geraldf
*/
#include <WProgram.h>
#include <Wire.h>
#include "SoftI2CMaster.h"
//--I2C--
const byte M_h = 0x52; //i2c address: motor at the back
const byte M_l = 0x54; //i2c address: motor at the left
const byte M_r = 0x56; //i2c address: motor at the right
const byte sdaPin = 4;
const byte sclPin = 5;
// LED Pins
int BackLED = 7;
int RightLED = 8;
int LeftLED = 9;
int ParseCommand(char *);
void I2CSend( int, int);
int BlinkLED(int );
extern "C" void __cxa_pure_virtual() {
}
int ledPin = 13; // LED connected to digital pin 13
int i = 0;
char str[255];
int inp;
char str1[] = "Test1";
// The setup() method runs once, when the sketch starts
void setup() {
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
pinMode (BackLED, OUTPUT);
pinMode (LeftLED, OUTPUT);
pinMode (RightLED, OUTPUT);
Serial.begin(9600);
Wire.begin();
Serial.println("Hello Master, I am online and waiting for your commands!");
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop() {
if (Serial.available() > 0 && i < 255) {
// read the incoming byte:
inp = Serial.read();
//digitalWrite(ledPin, HIGH); // set the LED on
//delay(500L); // wait for a second
//digitalWrite(ledPin, LOW); // set the LED off
//delay(500L); // wait for a second
// say what you got:
//Serial.print("I received: ");
//Serial.println(inp);
if (inp != 10) {
str[i++] = inp;
} else {
str[i] = '\0';
i = 0;
Serial.print("I received: ");
Serial.println(str);
if (ParseCommand(str) > 0) {
Serial.println("Invalid Command!");
}
}
}
}
int main(void) {
/* Must call init for arduino to work properly */
init();
setup();
for (;;) {
loop();
} // end for
} // end main
int ParseCommand(char* s) {
char cmd[255];
strcpy(cmd, s);
cmd[3] = '\0'; // command only (ML=, MR= or MH=)
if (strcmp(cmd, "ML=") == 0 || strcmp(cmd, "MR=") == 0
|| strcmp(cmd, "MH=") == 0) {
Serial.print("command ");
Serial.print(cmd);
Serial.println(" found!");
//parsing value now
int value = 0;
char v[5];
strcpy(v, s + 3);
Serial.print("value = ");
value = atoi(v);
Serial.println(value);
switch (cmd[1])
{
case 'H':
BlinkLED(1);
I2CSend(M_h,value);
break;
case 'L':
BlinkLED(2);
I2CSend(M_l,value);
break;
case 'R':
BlinkLED(4);
I2CSend(M_r,value);
break;
}
return (0);
}
else if (strcmp(s,"stop")== 0)
{
Serial.println("All Motors will stop!");
I2CSend(M_h,0);
I2CSend(M_l,0);
I2CSend(M_r,0);
BlinkLED(7);
return 0;
}
else
{
return (1);
}
return (0);
}
void I2CSend( int adr, int cmd)
{
// Wire.beginTransmission (adr);
// Wire.send(cmd);
// Wire.endTransmission();
SoftI2CMaster i2c = SoftI2CMaster( sdaPin,sclPin );
i2c.beginTransmission(adr);
i2c.send(cmd);
i2c.endTransmission();
}
int BlinkLED(int LED)
{
switch(LED)
{
case 1:
digitalWrite(BackLED, HIGH); // set the LED on
delay(100L);
break;
case 2:
digitalWrite(LeftLED, HIGH); // set the LED on
delay(100L);
break;
case 4:
digitalWrite(RightLED, HIGH); // set the LED on
delay(100L);
break;
case 3:
digitalWrite(BackLED, HIGH); // set the LED on
digitalWrite(LeftLED, HIGH); // set the LED on
delay(100L);
break;
case 7:
digitalWrite(BackLED, HIGH); // set the LED on
digitalWrite(LeftLED, HIGH); // set the LED on
digitalWrite(RightLED, HIGH); // set the LED on
delay(100L);
break;
}
digitalWrite(BackLED, LOW); // set the LED on
digitalWrite(LeftLED, LOW); // set the LED on
digitalWrite(RightLED, LOW); // set the LED on
return 0;
}
Liste der Anhänge anzeigen (Anzahl: 2)
Ich hab jetzt ein kleines Programm mit Bascom geschrieben, das den Konverter testet. Ez steuert jeden Motor einzeln hoch, indem es den Motorwert von 0 bis 130 alle 100ms um 1 erhöht, und zwar erst den Linke, dann den rechten und zum Schluss den hinteren Motor. Als Anzeige wird für jeden Motor eine LED angesteuert. Da bei mir die Motoren erst bei einm Wert ab 50 reagieren muss man ein wenig Gedult haben, bis der erste Motor läuft.
Hier das Programm, und als Anhang auch das HEX file dazu.
Code:
'===CHIP SETTINGS===
$regfile = "m328pdef.dat"
$framesize = 64
$swstack = 64
$hwstack = 64
$crystal = 16000000
$baud = 38400
'===SERIAL IN SETTINGS===
Config Serialout = Buffered , Size = 254
Config Serialin = Buffered , Size = 254
'===ADC SETTINGS===
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'avcc reference @ arduino =5V
'===PORT SETTINGS===
Config Scl = Portd.5 'for ESCs
Config Sda = Portd.4 'for ESCs
Config Pind.6 = Output 'servo
Portd.6 = 0 'servo
Config Pind.7 = Output 'led 1
Config Pinb.0 = Output 'led 2
Config Pinb.1 = Output 'led 3
Config Pinb.5 = Output 'Arduino LED_grn
'===DECLARATIONS===
'--Global--
'--I2C--
Const M_h = &H52 'i2c address: motor at the back
Const M_l = &H54 'i2c address: motor at the left
Const M_r = &H56 'i2c address: motor at the right
Dim Ms_h_i As Integer 'contains motor nominal value as integer
Dim Ms_r_i As Integer 'contains motor nominal value as integer
Dim Ms_l_i As Integer 'contains motor nominal value as integer
Dim Ms_h As Word 'converts motor nominal value
Dim Ms_r As Word 'converts motor nominal value
Dim Ms_l As Word 'converts motor nominal value
Dim Currentmotor As Integer
'--Subs--
Declare Sub Send_mots 'check and reshape motor signals and send them via i2c
'--Alias's
Led_1 Alias Portd.7
Led_2 Alias Portb.0
Led_3 Alias Portb.1
Led_grn Alias Portb.5 'a green led on the arduino mini pro
'===START CONDITIONS===
Set Led_1 'light up led's after reset
Set Led_2
Set Led_3
'--Variables-- 'prepare some variables
'Clear Serialin
'Clear Serialout
'--Startup 2--
Waitms 100
Start Adc
I2cinit
Currentmotor = 1
Ms_h = 0 : I2csend M_h , Ms_h 'turn off the motors
Ms_r = 0 : I2csend M_r , Ms_r
Ms_l = 0 : I2csend M_l , Ms_l
Led_grn = 0
Waitms 100
Reset Led_1 'turn off led's
Reset Led_2
Reset Led_3
'==============MAIN LOOP========================================================
'All this does is calling subs in a loop all the time
Do
Send_mots
Loop
End
'===MOTORS I2C==================================================================
Sub Send_mots
If Ms_l > 130 Then
Ms_l = 0
Currentmotor = Currentmotor + 1
If Currentmotor > 3 Then
Currentmotor = 1
End If
End If
If Ms_r > 130 Then
Ms_r = 0
Currentmotor = Currentmotor + 1
If Currentmotor > 3 Then
Currentmotor = 1
End If
End If
If Ms_h > 130 Then
Ms_h = 0
Currentmotor = Currentmotor + 1
If Currentmotor > 3 Then
Currentmotor = 1
End If
End If
If Currentmotor = 1 Then
Ms_l = Ms_l + 1
Set Led_1
Reset Led_2
Reset Led_3
End If
If Currentmotor = 2 Then
Ms_r = Ms_r + 1
Reset Led_1
Set Led_2
Reset Led_3
End If
If Currentmotor = 3 Then
Ms_h = Ms_h + 1
Reset Led_1
Reset Led_2
Set Led_3
End If
I2csend M_h , Ms_h
I2csend M_r , Ms_r
I2csend M_l , Ms_l
Waitms 100
End Sub
Liste der Anhänge anzeigen (Anzahl: 1)
Hmmm....
Weil mir dei Verkabelung am IMU eh nicht gefallen hat, hab ich hin komplett demontiert. Bei der Montage hab ich Heißkleber verwendet um die Platinen zu fixieren (mein Sekundenkleber war eingetrocknet und ich wollte den Cube unbedingt fertig machen). Das hat sich jetzt gerächt:
An einem Gyro ist mir ein Transistor abgerissen und unauffindbar verschwunden. Im Anhang hab ich den mal makiert. Ist das ein 22nF oder der 2,2nF? Und welche Bauform ist das? Dann kann ich mir vll nen Ersatz bei Reichelt holen.
Dann hab ich den ACC-Sensor mal allein angeschlossen weil der im montierten Zustand schon keine großen Ausschläge in der TriGUI gemeldet hat. Und das hat sich auch nicht geändert. Ist das normal, dass der ACC-Sensor die Gyros braucht um in der TriGUI sichtbare Ausschläge zu verursachen? Oder müsste der allein auch funktionieren?