Forum: Mikrocontroller und Digitale Elektronik stm32 timers synchronisieren in encoder mode


von Navid M. (Firma: mori) (navidmo198)


Lesenswert?

Hallo zusammen,

Ich muss 8 Timer von 2 Stm32f7 Nucleo Board im Encoder-Modus verwenden, 
um Encoder-Daten zu speichern. Aber ich muss die Timer synchronisieren. 
Dafür gibt es zwei Methoden: 1. Externe Clock 2. Master/Slave-Modus.

Aber in diesen 2 Modi kann man keine Timer im Encoder-Modus verwenden. 
Kann  jemand mir bitte helfen? Wie kann ich den Timer im Encoder-Modus 
synchronisieren?

von Uwe Bonnes (Gast)


Lesenswert?

Was soll "synchronisieren in encoder mode" bedeuten. Takt fuer die Timer 
kommt vom Encoder, da kannst Du nichts synchronisieren. Nur das Auslesen 
sollte moeglichst schnell hintereinander erfolgen, aber wenn Du die 
Timer zuegig hintereinander ausliest sehe ich da auch keine grosse 
Chance fuer  Jitter. Evt waehrend der Auslese Interrupts deaktivieren...

von Navid M. (Firma: mori) (navidmo198)


Lesenswert?

Danke für deine Antwort.

Ich habe 8 Timers von 2 Stm32F7 boards in encoder mode benutzt um die 
encoderinkremente zu lesen. Die 2 Boards und mein Programm funktionieren 
richtig, aber es gibt immer +/- 1ms Verzogerung zwischen Timers. (Z.B 
eine encoder zeigt die Werte 2000 in miliseconde 500 und die andere 
zeigt das in 501ms und die andere in 499ms)

Ich muss die Timers synchronisieren. Timers kann man mit external clock 
oder in Master slave mode synchronisieren, aber so man kann nicht mehr 
Timers in encoder mode benutzen.

von Jan H. (jan_h74) Flattr this


Lesenswert?

Wen ich das richtig verstehen :
Sie haben 2 STM32 F7 µ-controller
Jeden F7 µ ist verbunden mit ein motor-encoder mit A/B pulsen.
Sie wollen jetzt das beide µ-controller das gleiche Ergebnis von pulsen 
zaehlen (es geht um nur ein motor) ?

von Navid M. (Firma: mori) (navidmo198)


Lesenswert?

Ja genau. Die beiden Boards zeigen richtig. Aber es gibt eine 
Verzögerung zwischen boards. ein Stm32 zeigt das Ergebnis 1 ms früher 
oder später im Vergleich mit dem anderen.

: Bearbeitet durch User
von Jan H. (jan_h74) Flattr this


Lesenswert?

Ich siehe 2 mogliche Fehlerquellen :
1. Die counter in beide F7 werden nicht auf den identische moment auf 
"0" gezetst. Hier soll ich ueber eine GPIO und ISR die counter auf 0 
setzen. Damit ist eine synchronisierung in µs bereich machbar.
2. Wie werden die counter ausgelesen (usart, display)? Irgendwo muss die 
countervalue nach aussen kommen und interpretiert werden. Falls moglich 
auch hier mit ein GPIO und ISR die beide countervalues kopieren und den 
kopie nach aussen bringen.

von Navid M. (Firma: mori) (navidmo198)


Angehängte Dateien:

Lesenswert?

Ich habe CubeMx benutz. Timer habe ich in Encoder Mode eingestellt.
Dann habe ich die Channel A und B aktiviert:
HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_2);

Und die Encoderswerte ausgelesen mit:
encoder_count = __HAL_TIM_GET_COUNTER(&htim1);

Wie kann man Über eine GPIO und ISR die counter auf 0 setzen?
Sorry für viele Fragen. Ich habe nicht zu viele Erfahrungen.

von Jan H. (jan_h74) Flattr this


Lesenswert?

An jeden GPIO pin kann ein "Interrupt Service Routine" gekuppelt werden. 
Das ist ein Routine die unabhangig von den normale Ablauf ("loop") 
activiert werd wen ein GPIO-pin von Zustand wechselt. Das gleiche Signal 
muss naturlich an beide µ verbunden werden. Auch in cube kann das 
gemacht werden.
Werden die Zaehler jetzt genullt bei booten von  µ ? Steht en Motor dan, 
oder kann er schon drehen ? Wie werden den __HAL_TIM_GET_COUNTER(&htim1) 
sichtbar gemacht ? Wen das in der loop ist, sind die naturlich nicht 
synchronisiert. Beide loops laufen komplett unabhangig von ein ander.

von Navid M. (Firma: mori) (navidmo198)


Lesenswert?

Du meinst ich muss Die Werte nach einem Interrupt auslesen?
Also ich muss encoder_count = __HAL_TIM_GET_COUNTER(&htim1);  nach 
Interrupt machen? Dann wie kann ich Interrupts in jedem Mikro 
miteinander und mit anderem Mikro synchronisieren?
Bei booten Encoderswerte wird null, deswegen ich denke ja die Zähler 
werden genullt.
Motor ist unabhängig von diesem Projekt. Also es gibt ein Motor, der 
sich dreht. Der hat einen Inkrementalen Enkoder und ich muss die 
Inkremente vom Motor nur lesen.
Das ist mein Programm:
1
/* USER CODE BEGIN Header */
2
/**
3
  ******************************************************************************
4
  * @file           : main.c
5
  * @brief          : Main program body
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under BSD 3-Clause license,
13
  * the "License"; You may not use this file except in compliance with the
14
  * License. You may obtain a copy of the License at:
15
  *                        opensource.org/licenses/BSD-3-Clause
16
  *
17
  ******************************************************************************
18
  */
19
/* USER CODE END Header */
20
/* Includes ------------------------------------------------------------------*/
21
#include "main.h"
22
23
/* Private includes ----------------------------------------------------------*/
24
/* USER CODE BEGIN Includes */
25
26
/* USER CODE END Includes */
27
28
/* Private typedef -----------------------------------------------------------*/
29
/* USER CODE BEGIN PTD */
30
31
/* USER CODE END PTD */
32
33
/* Private define ------------------------------------------------------------*/
34
/* USER CODE BEGIN PD */
35
/* USER CODE END PD */
36
37
/* Private macro -------------------------------------------------------------*/
38
/* USER CODE BEGIN PM */
39
40
/* USER CODE END PM */
41
42
/* Private variables ---------------------------------------------------------*/
43
44
TIM_HandleTypeDef htim1;
45
46
/* USER CODE BEGIN PV */
47
int32_t encoder_count;
48
49
50
/* USER CODE END PV */
51
52
/* Private function prototypes -----------------------------------------------*/
53
void SystemClock_Config(void);
54
static void MX_GPIO_Init(void);
55
static void MX_TIM1_Init(void);
56
/* USER CODE BEGIN PFP */
57
58
/* USER CODE END PFP */
59
60
/* Private user code ---------------------------------------------------------*/
61
/* USER CODE BEGIN 0 */
62
63
/* USER CODE END 0 */
64
65
/**
66
  * @brief  The application entry point.
67
  * @retval int
68
  */
69
int main(void)
70
{
71
  /* USER CODE BEGIN 1 */
72
73
  /* USER CODE END 1 */
74
75
  /* MCU Configuration--------------------------------------------------------*/
76
77
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
78
  HAL_Init();
79
80
  /* USER CODE BEGIN Init */
81
82
  /* USER CODE END Init */
83
84
  /* Configure the system clock */
85
  SystemClock_Config();
86
87
  /* USER CODE BEGIN SysInit */
88
89
  /* USER CODE END SysInit */
90
91
  /* Initialize all configured peripherals */
92
  MX_GPIO_Init();
93
  MX_TIM1_Init();
94
  /* USER CODE BEGIN 2 */
95
96
 // HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_1);
97
//  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_2);
98
99
  HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_1);
100
    HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_2);
101
102
103
104
105
  /* USER CODE END 2 */
106
107
  /* Infinite loop */
108
  /* USER CODE BEGIN WHILE */
109
  while (1)
110
  {
111
    /* USER CODE END WHILE */
112
113
    /* USER CODE BEGIN 3 */
114
115
    encoder_count = __HAL_TIM_GET_COUNTER(&htim1);
116
    //encoder3 = __HAL_TIM_GET_COUNTER(&htim3);
117
   // encoder4 = __HAL_TIM_GET_COUNTER(&htim4);
118
119
  }
120
  /* USER CODE END 3 */
121
}
122
123
/**
124
  * @brief System Clock Configuration
125
  * @retval None
126
  */
127
void SystemClock_Config(void)
128
{
129
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
130
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
131
132
  /** Configure the main internal regulator output voltage
133
  */
134
  __HAL_RCC_PWR_CLK_ENABLE();
135
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
136
  /** Initializes the RCC Oscillators according to the specified parameters
137
  * in the RCC_OscInitTypeDef structure.
138
  */
139
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
140
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
141
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
142
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
143
  RCC_OscInitStruct.PLL.PLLM = 8;
144
  RCC_OscInitStruct.PLL.PLLN = 192;
145
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
146
  RCC_OscInitStruct.PLL.PLLQ = 2;
147
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
148
  {
149
    Error_Handler();
150
  }
151
  /** Activate the Over-Drive mode
152
  */
153
  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
154
  {
155
    Error_Handler();
156
  }
157
  /** Initializes the CPU, AHB and APB buses clocks
158
  */
159
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
160
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
161
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
162
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
163
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
164
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
165
166
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
167
  {
168
    Error_Handler();
169
  }
170
}
171
172
/**
173
  * @brief TIM1 Initialization Function
174
  * @param None
175
  * @retval None
176
  */
177
static void MX_TIM1_Init(void)
178
{
179
180
  /* USER CODE BEGIN TIM1_Init 0 */
181
182
  /* USER CODE END TIM1_Init 0 */
183
184
  TIM_Encoder_InitTypeDef sConfig = {0};
185
  TIM_MasterConfigTypeDef sMasterConfig = {0};
186
187
  /* USER CODE BEGIN TIM1_Init 1 */
188
189
  /* USER CODE END TIM1_Init 1 */
190
  htim1.Instance = TIM1;
191
  htim1.Init.Prescaler = 0;
192
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
193
  htim1.Init.Period = 65535;
194
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
195
  htim1.Init.RepetitionCounter = 0;
196
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
197
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
198
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
199
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
200
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
201
  sConfig.IC1Filter = 0;
202
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
203
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
204
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
205
  sConfig.IC2Filter = 0;
206
  if (HAL_TIM_Encoder_Init(&htim1, &sConfig) != HAL_OK)
207
  {
208
    Error_Handler();
209
  }
210
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
211
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
212
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
213
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
214
  {
215
    Error_Handler();
216
  }
217
  /* USER CODE BEGIN TIM1_Init 2 */
218
219
  /* USER CODE END TIM1_Init 2 */
220
221
}
222
223
/**
224
  * @brief GPIO Initialization Function
225
  * @param None
226
  * @retval None
227
  */
228
static void MX_GPIO_Init(void)
229
{
230
  GPIO_InitTypeDef GPIO_InitStruct = {0};
231
232
  /* GPIO Ports Clock Enable */
233
  __HAL_RCC_GPIOC_CLK_ENABLE();
234
  __HAL_RCC_GPIOH_CLK_ENABLE();
235
  __HAL_RCC_GPIOA_CLK_ENABLE();
236
  __HAL_RCC_GPIOB_CLK_ENABLE();
237
  __HAL_RCC_GPIOE_CLK_ENABLE();
238
  __HAL_RCC_GPIOD_CLK_ENABLE();
239
  __HAL_RCC_GPIOG_CLK_ENABLE();
240
241
  /*Configure GPIO pin Output Level */
242
  HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);
243
244
  /*Configure GPIO pin Output Level */
245
  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_RESET);
246
247
  /*Configure GPIO pin : USER_Btn_Pin */
248
  GPIO_InitStruct.Pin = USER_Btn_Pin;
249
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
250
  GPIO_InitStruct.Pull = GPIO_NOPULL;
251
  HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);
252
253
  /*Configure GPIO pins : RMII_MDC_Pin RMII_RXD0_Pin RMII_RXD1_Pin */
254
  GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin;
255
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
256
  GPIO_InitStruct.Pull = GPIO_NOPULL;
257
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
258
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
259
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
260
261
  /*Configure GPIO pins : RMII_REF_CLK_Pin RMII_MDIO_Pin RMII_CRS_DV_Pin */
262
  GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin;
263
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
264
  GPIO_InitStruct.Pull = GPIO_NOPULL;
265
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
266
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
267
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
268
269
  /*Configure GPIO pins : LD1_Pin LD3_Pin LD2_Pin */
270
  GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
271
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
272
  GPIO_InitStruct.Pull = GPIO_NOPULL;
273
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
274
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
275
276
  /*Configure GPIO pin : RMII_TXD1_Pin */
277
  GPIO_InitStruct.Pin = RMII_TXD1_Pin;
278
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
279
  GPIO_InitStruct.Pull = GPIO_NOPULL;
280
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
281
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
282
  HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct);
283
284
  /*Configure GPIO pins : STLK_RX_Pin STLK_TX_Pin */
285
  GPIO_InitStruct.Pin = STLK_RX_Pin|STLK_TX_Pin;
286
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
287
  GPIO_InitStruct.Pull = GPIO_NOPULL;
288
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
289
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
290
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
291
292
  /*Configure GPIO pin : PG6 */
293
  GPIO_InitStruct.Pin = GPIO_PIN_6;
294
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
295
  GPIO_InitStruct.Pull = GPIO_NOPULL;
296
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
297
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
298
299
  /*Configure GPIO pin : USB_OverCurrent_Pin */
300
  GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
301
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
302
  GPIO_InitStruct.Pull = GPIO_NOPULL;
303
  HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);
304
305
  /*Configure GPIO pins : USB_SOF_Pin USB_ID_Pin USB_DM_Pin USB_DP_Pin */
306
  GPIO_InitStruct.Pin = USB_SOF_Pin|USB_ID_Pin|USB_DM_Pin|USB_DP_Pin;
307
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
308
  GPIO_InitStruct.Pull = GPIO_NOPULL;
309
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
310
  GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
311
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
312
313
  /*Configure GPIO pin : USB_VBUS_Pin */
314
  GPIO_InitStruct.Pin = USB_VBUS_Pin;
315
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
316
  GPIO_InitStruct.Pull = GPIO_NOPULL;
317
  HAL_GPIO_Init(USB_VBUS_GPIO_Port, &GPIO_InitStruct);
318
319
  /*Configure GPIO pins : RMII_TX_EN_Pin RMII_TXD0_Pin */
320
  GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin;
321
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
322
  GPIO_InitStruct.Pull = GPIO_NOPULL;
323
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
324
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
325
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
326
327
}
328
329
/* USER CODE BEGIN 4 */
330
331
/* USER CODE END 4 */
332
333
/**
334
  * @brief  This function is executed in case of error occurrence.
335
  * @retval None
336
  */
337
void Error_Handler(void)
338
{
339
  /* USER CODE BEGIN Error_Handler_Debug */
340
  /* User can add his own implementation to report the HAL error return state */
341
  __disable_irq();
342
  while (1)
343
  {
344
  }
345
  /* USER CODE END Error_Handler_Debug */
346
}
347
348
#ifdef  USE_FULL_ASSERT
349
/**
350
  * @brief  Reports the name of the source file and the source line number
351
  *         where the assert_param error has occurred.
352
  * @param  file: pointer to the source file name
353
  * @param  line: assert_param error line source number
354
  * @retval None
355
  */
356
void assert_failed(uint8_t *file, uint32_t line)
357
{
358
  /* USER CODE BEGIN 6 */
359
  /* User can add his own implementation to report the file name and line number,
360
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
361
  /* USER CODE END 6 */
362
}
363
#endif /* USE_FULL_ASSERT */
364
365
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

: Bearbeitet durch User
von Jan H. (jan_h74) Flattr this


Lesenswert?

Es ist mir immer noch unklar wie die Counter werte nach "aussen" gehen. 
In der main loop steht nur "encoder_count = 
__HAL_TIM_GET_COUNTER(&htim1);" Wie wissen sie dan das encouder_count 
verschiedene Werte haben in die 2 µ ?

von Navid M. (Firma: mori) (navidmo198)


Angehängte Dateien:

Lesenswert?

Ich habe Cube Monitor benutzt die Daten zu speichern. Das gibt ein CSV. 
File. Darin kann man gut die Werte und Zeit sehen.
im Foto die erste Spalte ist die Anzahl von Inkremente.
2. und 3. Spalte ist die Zeit für Encoder1 und Encoder2.
Wie im Foto zu sehen ist Anzahl der Inkremente 88 ist für der erster 
Encoder in der Zeit 32ms but für zweiter Encoder in der 33ms.
Manchmal das ist gleich manchmal das hat +-1ms Differenz.

: Bearbeitet durch User
von Jan H. (jan_h74) Flattr this


Lesenswert?

Eigenlich ist ihre problem das Cube Monitor diese 1ms nicht immer 
einhalt ?
Da fehlen ab und zu eine Daten satz. Ich glaube nicht das dieses 
Verfahren auf millisecunden genau die Daten speichert ! Können sie nicht 
einfach mal die Motor stoppen, beide µ-controller resetten (counter =0), 
motor starten, motor wieder stoppen, und dan die erste und letzte 
Zaehlerstanden vergleichen ? Wen diese gleich sind, ist das encoder 
auswerten doch IO ?

von Peter D. (peda)


Lesenswert?

Timer im Zählermode werden nicht genullt. Beim Nullen könnte ein 
gleichzeitiger Zählimpuls verloren gehen. Daher merkt man sich immer nur 
den vorherigen Zählerwert und bildet die Differenz zum aktuellen 
Zählerwert. Der Zählerwert ist quasi read-only.
Will man an einer Referenzmarke den Zählerstand als Nullwert speichern, 
dann liest man ihn genau an der Referenzmarke aus.

Die 1ms Unterschiede liegen an der Erstellung der CSV-Datei. Stehen die 
Encoder still, sollten die Differenzen zum Startwert wieder exakt gleich 
sein.

von Navid M. (Firma: mori) (navidmo198)


Angehängte Dateien:

Lesenswert?

Danke für Ihre Antwort.
Aber ich denke Stm32 kann nicht die schnelle Änderungen synchron zeigen. 
Ich habe den gleichen Encoder an 4 Timers angeschlossen. Theoretisch 
müssen die Werte immer gleich sein. Aber wie im Foto zu sehen ist bei 
der Änderung gibt es immer Unterschied. Aber wenn der Encoder in 
Standstill ist zeigen alle Timers richtig und gleiche Werte.

von Peter D. (peda)


Lesenswert?

Ich vermute mal, das Debuggen erfolgt über USB und die 1ms Unterschied 
sind einfach die Pollingzeit des USB. Der Debugger kann daher nicht 
kleiner als 1ms auflösen.

von Navid M. (Firma: mori) (navidmo198)


Lesenswert?

Kann man irgendwie die Daten in Mikro speichern? So die Aufzeichnung der 
Daten ist unabhängig von USB.

von Jan H. (jan_h74) Flattr this


Lesenswert?

Ja, das geht. Dan wird das problem verschoben nach "Diese Daten mussen 
ms genau auf beide µ gespeichert werden".
Diese Zeitpunkt kann ueber eine GPIO "synchronisiert" werden ! Ein µ 
wird master, und gibt jeden secunde / milli secunde ein puls (GPIOpin 
High/Low)an die andere µ. Diese µ reagiert auf diesen puls mit eine 
interrupt. In die interrupt wird dan die zaehler wert gespeichert.
Damit erreichen sie locker eine synchronisierung von 100 µsec.
1
volatile int encodercounter[1000];
2
Interrupt_GPIO{
3
encodercounter[count]=zaehler;
4
count++;
5
if (count>998)count=0;
6
}

von Gerald M. (gerald_m17)


Lesenswert?

Hallo Navid,

vielleicht erklärst du Mal was genau du erreichen willst.
Gehe einfach davon aus, dass die Encoder Counter in beiden 
Mikrocontrollern das gleiche anzeigen. Zumindest sofern beim einschalten 
der Controller der Encoder stillsteht.
Das was du gerade hast, ist ein Ausleseproblem. Ist das in deinem Fall 
überhaupt ein wirkliches Problem? Was machst du später mit den Werten?

von Navid M. (Firma: mori) (navidmo198)


Lesenswert?

Hallo Gerald,
Ich will die Encoderwerte messen. Ich habe 2 Stm32f7 Board benutzt.
Mein Problem ist das, dass ich mit gleichem Encoder unterschiedliche 
Werte mit Mikro Boards auslese.
Die Werte sind richtig aber ein Board zeigt die Werte mit +-1ms 
Verzögerung.
Ich habe ein external Clock auch benutzt um Clock zu synchronisieren 
aber das Problem gibt es noch.

von Stefan F. (Gast)


Lesenswert?

Navid M. schrieb:
> Ich will die Encoderwerte messen.

Das kann alles und nichts bedeuten. "Ich will Würfel messen" sagt genau 
so wenig aus.

von Peter D. (peda)


Lesenswert?

Navid M. schrieb:
> Ich will die Encoderwerte messen.

Was willst Du denn messen?

Um die Encoderauswertung zu überprüfen, fährt man eine Strecke hin und 
dann 10 Teilstrecken zurück. Danach muß man wieder beim gleichen 
Zählerstand angekommen sein, sonst stimmt was nicht.

von Gerald M. (gerald_m17)


Lesenswert?

Hallo Navid, das ist kein Problem einer nicht synchronen Clock. Das ist 
ein Problem wie du die Werte ausliest.

Wenn du dir einmal Mühe bei deiner Antwort auf die Frage gibst, was du 
machen willst, sage ich dir, wie man das typischerweise richtig macht 
(dazu gehört beispielsweise kein Cube Monitor). Ich gebe dir dann sogar 
ein Beispiel dafür, wann und warum eine Clock synchronisiert sein muss.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.