Member 13867267 Ответов: 1

Как ввести и сохранить значения на моем arduino, чтобы использовать их позже?


я хочу создать список, который содержит число неопределенной ссылки, состоящее из 8 чисел :

например :

28546455
95685615
55925555
59295525
и т.д.......

эти цифры можно ввести с помощью клавиатуры

каждая ссылка содержит 2 параметра :

1.скорость
2.шаги

пример:

28546455 --> скорость : 500
--> шаги : 10000

95685615 --> скорость : 300
-->шаги : 20000

и т.д..........

я сделал эту программу, но она, кажется, не работает??
кто-нибудь поможет??

Что я уже пробовал:

<pre>#include "Reference.h"
#include <Keypad.h>

char keypad_referenceNumber[9];
char keypad_SPEED[4];
char keypad_STEPS[6];

int counter = 0;

const byte ROWS =4;
const byte COLS =3;

char keys[ROWS][COLS]={
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[ROWS]={8,7,6,5};
byte colPins[COLS]={4,3,2};

Keypad keypad = Keypad (makeKeymap(keys),rowPins,colPins,ROWS,COLS);

int data_referenceNumber;
int data_SPEED;
int data_STEPS;

List *myList;


void setup() {
  // put your setup code here, to run once:
  
Serial.begin(9600);
List *myList = initialisation();
}

void loop() {
  // put your main code here, to run repeatedly:
  
 getreferenceNumber();
 getSPEED();
 getSTEPS(); 
  
 addNewReference(myList,data_referenceNumber,data_SPEED,data_STEPS);
 displayList(myList);

}
void getreferenceNumber(){
  
  char key = keypad.getKey();
  
  if (key!=NO_KEY){
    
    keypad_referenceNumber[counter++]= key;
    keypad_referenceNumber[counter]= '\0';
    
    Serial.print(key);

    if (key == '#'){
      
      data_referenceNumber= atoi(keypad_referenceNumber);
      
      Serial.println(data_referenceNumber);
      
      counter = 0;
    }
  }
}

void getSPEED(){
  
   char key = keypad.getKey();
  if (key!=NO_KEY){
    keypad_SPEED[counter++]= key;
    keypad_SPEED[counter]= '\0';

    if (key == '#'){
      data_SPEED= atoi(keypad_SPEED);
      Serial.println(data_SPEED);
      counter = 0;
    }
  } 
}

void getSTEPS(){
   char key = keypad.getKey();
  if (key!=NO_KEY){
    keypad_STEPS[counter++]= key;
    keypad_STEPS[counter]= '\0';

    if (key == '#'){
      data_STEPS= atoi(keypad_STEPS);
      Serial.println(data_STEPS);
      counter = 0;
    }
  }
}

List *initialisation(){
  List *list;
  References *references;
  
  if (list == NULL || references == NULL){
exit (EXIT_FAILURE);
}

references->referenceNumber = 0;
references->SPEED = 0;
references->STEPS = 0;

references->next = NULL;
list->firstElement = references;

 return list;
};

// x : reference number
// y : speed
// z : steps

void addNewReference(List *list, int x, int y, int z){
  References *newReference;
  
  if (list == NULL || newReference == NULL){
    exit (EXIT_FAILURE);
  }
  newReference->referenceNumber = x;
  newReference->SPEED = y;
  newReference->STEPS = z;

  newReference->next = list->firstElement;
  
  list->firstElement = newReference;   
}

void displayList(List *list){
  if (list == NULL){
    exit (EXIT_FAILURE);
  }
  References *current = list->firstElement;

  while(current!=NULL){
    Serial.println(current->referenceNumber);
    Serial.println(current->SPEED);
    Serial.println(current->STEPS);
    
    current = current->next;
  }
  Serial.println("NULL");
}



а это и есть <reference.h>

#ifndef _REFERENCE_H_
#define _REFERENCE_H_

typedef struct References References;
struct References{ 
  int referenceNumber;
  int SPEED;
  int STEPS;  
  References *next;    
};

typedef struct List List;
struct List{
  References *firstElement; 
};

#endif

1 Ответов

Рейтинг:
8

Jochen Arndt

Избегайте использования глобальных переменных. Трудно отследить, какие значения на самом деле хранятся в них и являются возможным источником ошибок.

Если программа работает не так, как ожидалось, вы должны использовать отладчик для пошагового просмотра кода и просмотра переменных. Если это невозможно на вашем Arduino, напишите приложение сначала на ПК, чтобы протестировать и отладить его (чтение ввода, а затем с клавиатуры).

У вас есть ошибка проектирования / логики:
Чтение входных данных, состоящих из нескольких символов, должно выполняться в цикле, но у вас нет такого в ваших подпрограммах ввода.

Было бы также проще написать функцию, которая считывает числовой ввод и возвращает его для всех трех значений, вместо того чтобы предоставлять три функции, которые в основном делали бы то же самое:

int get_num_from_keypad()
{
    int count = 0;
    int value = 0;
    char key;
    char buf[9];
    
    key = keypad.getKey();
    while (key != NO_KEY)
    {
        Serial.print(key);
        if (key == '#')
        {
            buf[count] = '\0';
            value = atoi(buf);
            break;
        }
        buf[count++] = key;
        /* EDIT: Forgot this */
        key = keypad.getKey();
    }
    return value;
}

Прочтите о связанных списках, прежде чем пытаться их использовать. Они должны использовать динамическое распределение памяти с помощью malloc() или calloc().

Если у вас есть известное максимальное количество вводимых данных, вы даже можете избежать использования связанного списка и вместо этого использовать массив фиксированного размера и переменную, содержащую количество наборов записей:
int ref_count = 0;
References refs[MAX_REFS];

/* ... */

void loop()
{
    if (ref_count < MAX_REFS)
    {
        refs[ref_count].referenceNumber = get_num_from_keypad();
        refs[ref_count].SPEED = get_num_from_keypad();
        refs[ref_count].STEPS = get_num_from_keypad();
        ref_count++;
    }
}
Чтобы отобразить этот список просто выполните цикл до но исключая ref_count.

Обратите также внимание, что все имена в верхнем регистре не должны использоваться для переменных. Рекомендуется использовать их исключительно для определения препроцессора.

[РЕДАКТИРОВАТЬ]
Цитата:
поскольку в arduino нет отладчика, можете ли вы порекомендовать мне тот, который я могу использовать

что касается распределения памяти, то я не знаю, как работать с памятью arduino, поэтому я собираюсь протестировать предложенный вами массив

Как уже было предложено вы можете сначала разработать свою программу на ПК с помощью getchar() для ввода и printf() для выхода.

Вы используете C, который обеспечивает уже упомянутое malloc() и calloc() стандартные библиотечные функции. Просто используйте их, как и на любой другой платформе (кроме того, что у Arduino не так много памяти, и они потерпят неудачу, когда запросят слишком много памяти).
[/РЕДАКТИРОВАТЬ]


Member 13867267

это мой первый раз, когда я использую эту платформу, я буду более осторожен
спасибо за ваши ответы они действительно полезны