Плоттер с ЧПУ НА базе ардуино, необходимо устранить ошибку (invalid conversion from 'char' to 'char*' [-fpermissive]indexY = '\0';
ВОТ КОД...
#include <Servo.h>
#include <AFMotor.h>
#define LINE_BUFFER_LENGTH 512
char STEP = MICROSTEP ;
// Положение сервопривода для подъема и опускания
const int penZUp = 95;
const int penZDown = 83;
// Сервопривод на ШИМ-выводе 10
const int penServoPin =10 ;
// Должно быть правильно для DVD-степперов, но здесь не слишком важно
const int stepsPerRevolution = 48;
// создать объект сервопривода для управления сервоприводом
Servo penServo;
// Инициализируйте степперы для осей X и Y, используя эти контакты Arduino для H-моста L293D
AF_Stepper myStepperY(stepsPerRevolution,1);
AF_Stepper myStepperX(stepsPerRevolution,2);
/* Structures, global variables */
struct point {
float x;
float y;
float z;
};
// Текущее положение
struct point actuatorPos;
// Настройки рисования, должно быть OK
float StepInc = 1;
int StepDelay = 0;
int LineDelay =0;
int penDelay = 50;
// Мотор шагает на 1 миллиметр.
// Используйте тестовый скетч, чтобы пройти 100 шагов. Измерьте длину лески.
// Рассчитать шаги на мм. Войдите сюда.
float StepsPerMillimeterX = 100.0;
float StepsPerMillimeterY = 100.0;
// Пределы чертежа робота, мм
// Хорошо, для начала. При хорошей калибровке может достигать 50 мм.
float Xmin = 0;
float Xmax = 40;
float Ymin = 0;
float Ymax = 40;
float Zmin = 0;
float Zmax = 1;
float Xpos = Xmin;
float Ypos = Ymin;
float Zpos = Zmax;
// Установите значение true, чтобы получить отладочный вывод.
boolean verbose = false;
// Необходимо интерпретировать
// G1 для перемещения
// G4 P300 (ожидание 150 мс)
// M300 S30 (ручка вниз)
// M300 S50 (ручка вверх)
// Отбросьте что-нибудь с (
// Отбросить любую другую команду!
/**********************
* void setup() - Initialisations
***********************/
void setup() {
// Настройка
Serial.begin( 9600 );
penServo.attach(penServoPin);
penServo.write(penZUp);
delay(100);
// Уменьшить при необходимости
myStepperX.setSpeed(600);
myStepperY.setSpeed(600);
// Установить и переместить в исходное положение по умолчанию
// ТБД
// Уведомления!!!
Serial.println("Mini CNC Plotter alive and kicking!");
Serial.print("X range is from ");
Serial.print(Xmin);
Serial.print(" to ");
Serial.print(Xmax);
Serial.println(" mm.");
Serial.print("Y range is from ");
Serial.print(Ymin);
Serial.print(" to ");
Serial.print(Ymax);
Serial.println(" mm.");
}
/**********************
* void loop() - Main loop
***********************/
void loop()
{
delay(100);
char line[ LINE_BUFFER_LENGTH ];
char c;
int lineIndex;
bool lineIsComment, lineSemiColon;
lineIndex = 0;
lineSemiColon = false;
lineIsComment = false;
while (1) {
// Последовательный прием - В основном от Grbl, добавлена поддержка точки с запятой
while ( Serial.available()>0 ) {
c = Serial.read();
if (( c == '\n') || (c == '\r') ) { // Достигнут конец строки
if ( lineIndex > 0 ) { // Строка завершена. Тогда казните!
line[ lineIndex ] = '\0'; // Завершение строки
if (verbose) {
Serial.print( "Received : ");
Serial.println( line );
}
processIncomingLine( line, lineIndex );
lineIndex = 0;
}
else {
// Пустая строка или строка комментария. Пропустить блок.
}
lineIsComment = false;
lineSemiColon = false;
Serial.println("ok");
}
else {
if ( (lineIsComment) || (lineSemiColon) ) { // Выбросить все символы комментария
if ( c == ')' ) lineIsComment = false; // Конец комментария. Возобновление линии.
}
else {
if ( c <= ' ' ) { // Выбросить пробелы и управляющие символы
}
else if ( c == '/' ) { // Удаление блока не поддерживается. Игнорируйте символ.
}
else if ( c == '(' ) { // Включить флаг комментариев и игнорировать все символы до ')' или EOL.
lineIsComment = true;
}
else if ( c == ';' ) {
lineSemiColon = true;
}
else if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) {
Serial.println( "ERROR - lineBuffer overflow" );
lineIsComment = false;
lineSemiColon = false;
}
else if ( c >= 'a' && c <= 'z' ) { // Upcase нижний регистр
line[ lineIndex++ ] = c-'a'+'A';
}
else {
line[ lineIndex++ ] = c;
}
}
}
}
}
}
void processIncomingLine( char* line, int charNB ) {
int currentIndex = 0;
char buffer[ 64 ]; // Надеюсь, что 64 достаточно для 1 параметра
struct point newPos;
newPos.x = 0.0;
newPos.y = 0.0;
// Необходимо интерпретировать
// G1 для перемещения
// G4 P300 (ожидание 150 мс)
// G1 X60 Y30
// G1 X30 Y50
// M300 S30 (ручка вниз)
// M300 S50 (ручка вверх)
// Отбросьте что-нибудь с (
// Отбросить любую другую команду!
while( currentIndex < charNB ) {
switch ( line[ currentIndex++ ] ) { // Выберите команду, если в любом
case 'U':
penUp();
break;
case 'D':
penDown();
break;
case 'G':
buffer[0] = line[ currentIndex++ ]; // /!\ Грязный - работает только с 2-значными командами
// buffer[ 1] = строка [currentIndex++ ];
// buffer[2] = '\0';
buffer[1] = '\0';
switch ( atoi( buffer ) ){ //Выберите команду G
case 0: // G00 & G01 - Движение или быстрое движение. То же самое и здесь
case 1:
// /!\ Грязный - Предположим, что X находится перед Y
char* indexX = strchr( line+currentIndex, 'X' ); // Получить позицию X/Y в строке (если таковая имеется)
char* indexY = strchr( line+currentIndex, 'Y' );
if ( indexY <= 0 ) {
newPos.x = atof( indexX + 1);
newPos.y = actuatorPos.y;
}
else if ( indexX <= 0 ) {
newPos.y = atof( indexY + 1);
newPos.x = actuatorPos.x;
}
else {
newPos.y = atof( indexY + 1);
indexY = '\0';
newPos.x = atof( indexX + 1);
}
drawLine(newPos.x, newPos.y );
// Serial.println("ок");
actuatorPos.x = newPos.x;
actuatorPos.y = newPos.y;
break;
}
break;
case 'M':
buffer[0] = line[ currentIndex++ ]; ///!\ Грязный - работает только с 3-значными командами
buffer[1] = line[ currentIndex++ ];
buffer[2] = line[ currentIndex++ ];
buffer[3] = '\0';
switch ( atoi( buffer ) ){
case 300:
{
char* indexS = strchr( line+currentIndex, 'S' );
float Spos = atof( indexS + 1);
// Serial.println("ок");
if (Spos == 30) {
penDown();
}
if (Spos == 50) {
penUp();
}
break;
}
case 114: // M114 - Позиция возврата
Serial.print( "Absolute position : X = " );
Serial.print( actuatorPos.x );
Serial.print( " - Y = " );
Serial.println( actuatorPos.y );
break;
default:
Serial.print( "Command not recognized : M");
Serial.println( buffer );
}
}
}
}
/*********************************
* Draw a line from (x0;y0) to (x1;y1).
* Bresenham algo from https://www.marginallyclever.com/blog/2013/08/how-to-build-an-2-axis-arduino-cnc-gcode-interpreter/
* int (x1;y1) : Starting coordinates
* int (x2;y2) : Ending coordinates
**********************************/
void drawLine(float x1, float y1) {
if (verbose)
{
Serial.print("fx1, fy1: ");
Serial.print(x1);
Serial.print(",");
Serial.print(y1);
Serial.println("");
}
// Приведите инструкции в определенные рамки
if (x1 >= Xmax) {
x1 = Xmax;
}
if (x1 <= Xmin) {
x1 = Xmin;
}
if (y1 >= Ymax) {
y1 = Ymax;
}
if (y1 <= Ymin) {
y1 = Ymin;
}
if (verbose)
{
Serial.print("Xpos, Ypos: ");
Serial.print(Xpos);
Serial.print(",");
Serial.print(Ypos);
Serial.println("");
}
if (verbose)
{
Serial.print("x1, y1: ");
Serial.print(x1);
Serial.print(",");
Serial.print(y1);
Serial.println("");
}
// Преобразование координат в шаги
x1 = (int)(x1*StepsPerMillimeterX);
y1 = (int)(y1*StepsPerMillimeterY);
float x0 = Xpos;
float y0 = Ypos;
// Выясним изменение для координат
long dx = abs(x1-x0);
long dy = abs(y1-y0);
int sx = x0<x1 ? StepInc : -StepInc;
int sy = y0<y1 ? StepInc : -StepInc;
long i;
long over = 0;
if (dx > dy) {
for (i=0; i<dx; ++i) {
myStepperX.onestep(sx,STEP);
over+=dy;
if (over>=dx) {
over-=dx;
myStepperY.onestep(sy,STEP);
}
delay(StepDelay);
}
}
else {
for (i=0; i<dy; ++i) {
myStepperY.onestep(sy,STEP);
over+=dx;
if (over>=dy) {
over-=dy;
myStepperX.onestep(sx,STEP);
}
delay(StepDelay);
}
}
if (verbose)
{
Serial.print("dx, dy:");
Serial.print(dx);
Serial.print(",");
Serial.print(dy);
Serial.println("");
}
if (verbose)
{
Serial.print("Going to (");
Serial.print(x0);
Serial.print(",");
Serial.print(y0);
Serial.println(")");
}
// Задержка перед отправкой любых следующих строк
delay(LineDelay);
// Обновить позиции
Xpos = x1;
Ypos = y1;
}
// Поднимает перо
void penUp() {
penServo.write(penZUp);
delay(penDelay);
Zpos=Zmax;
digitalWrite(15, LOW);
digitalWrite(16, HIGH);
if (verbose) {
Serial.println("Pen up!");
}
}
// Опускает pen
void penDown() {
penServo.write(penZDown);
delay(penDelay);
Zpos=Zmin;
digitalWrite(15, HIGH);
digitalWrite(16, LOW);
if (verbose) {
Serial.println("Pen down.");
}
}
ВОТ В ЧЕМ ОШИБКА
C:\Users\Downloads\sketch_apr01a\sketch_apr01a.ino: In function 'void processIncomingLine(char*, int)':
C:\Users\Downloads\sketch_apr01a\sketch_apr01a.ino:224:20: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
indexY = '\0';
^~~~
@mallah vishnu, 👍-1
Обсуждение1 ответ
▲ 1
Строка должна гласить indexY[0] = '\0';
для компиляции. Но я думаю, что вы можете просто удалить всю строку, так как это манипулирует входным аргументом функции, который не используется дальше.
,
@PMF
Смотрите также:
- Как заставить сервопривод вращаться на угол больше 180°
- Серво не двигается
- Код, из-за которого серводвигатель не работает!
- НУЖНА помощь с серводвигателем
- Как использовать этот конкретный экран arduino
- Сервопривод с высоким крутящим моментом 6 В не будет работать на моторном щитке?
- Как заставить Arduino выполнять определенное действие, когда компьютер заблокирован / разблокирован?
- Почему Adafruit motor shield не крутит моторы?
и что должна делать линия?
Индексный[0] = '\0';
?, @JurajВы должны были хотя бы увидеть предупреждение относительно
if ( indexY <= 0 ) {
до ошибки, на которой вы сосредоточились.strchr
не возвращает индекс; он возвращает указатель, который может быть или не быть нулевым указателем., @timemage