Pages: 1 ... 7 8 [9]   Go Down
Author Topic: From linear to exponential PWM output  (Read 14646 times)
0 Members and 2 Guests are viewing this topic.
Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13478
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


try this variation of the code

Code:
void fillLookupTable()
{
  speedstartValueold = speedstartValue;
  switchpointXValueold = switchpointXValue;
  switchpointYValueold = switchpointYValue;
 
  switchpointXValue = constrain (switchpointXValue,deadbandXvalue, 255);
  switchpointYValue = constrain(switchpointYValue,speedstartValue, 255);
 
  Serial.print("B,");
  Serial.println(speedstartValue);
  Serial.print("C,");
  Serial.println(switchpointXValue);
  Serial.print("D,");
  Serial.println(switchpointYValue);
  Serial.println(deadbandXvalue);

  for (int i = 0; i < deadbandXvalue; i++)
      lookupTable[i] = 0;

  for (int i = deadbandXvalue; i < switchpointXValue; i++) 
      lookupTable[i] = map(i, 0, switchpointXValue, speedstartValue, switchpointYValue);

  for (int i = switchpointXValue; i < 256; i++) 
      lookupTable[i] =  map(i, switchpointXValue, 255, switchpointYValue, 255 ); 
     
    streamUp();
}   

makes the code a bit more straightforward, as it has clearly 3 parts

What is the output of above function? as expected?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

The Netherlands
Offline Offline
Sr. Member
****
Karma: 4
Posts: 330
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Rob,

Output is the same.
The lookuptable is filled correctly again.
I checked with Serial.print and the first speed value outside deadbandXValue is 104.

in the Void loop this where the speed values which use the lookuptable are coming from.
 
Code:
//  +++++++++++++++  regular speed - brake mode  +++++++++++++++

  sensorRawValue = analogRead(sensorspeedPin); // read the raw value from the linear hall sensor
  sensorRawValue = constrain(sensorRawValue, sensorMin, sensorMax); // constrain the maximum value to 255
  sensorValue = map(sensorRawValue, sensorMin, sensorMax, 0, 255); // map the calibration to the sensor reading from the hall sensor
  sensormappedValue = map(sensorValue, deadbandXvalue, 255, speedstartValue, 255); // full linear control mapped with startspeed
  
  //  ++++  curve section  +++++++
  //speedfinalValue = sensormappedValue;
  speedfinalValue = lookupTable[sensormappedValue];
  //  ++++  curve section  +++++++

Codewise the speedfinalValue clearly looks into the sensormappedValue or am I mistaken?

Paco
« Last Edit: November 18, 2012, 10:14:38 am by backbone » Logged

Never to old to learn and I learn every day

The Netherlands
Offline Offline
Sr. Member
****
Karma: 4
Posts: 330
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks to Rob the problem is solved.

By removing one line and chaning one variable inside the lookuptable.
here the correct code.

Code:
//  +++++++++++++++  regular speed - brake mode  +++++++++++++++

  sensorRawValue = analogRead(sensorspeedPin); // read the raw value from the linear hall sensor
  sensorRawValue = constrain(sensorRawValue, sensorMin, sensorMax); // constrain the maximum value to 255
  sensorValue = map(sensorRawValue, sensorMin, sensorMax, 0, 255); // map the calibration to the sensor reading from the hall sensor
   
  //  ++++  curve section  +++++++
  speedfinalValue = lookupTable[sensorValue];
  //  ++++  curve section  +++++++
Logged

Never to old to learn and I learn every day

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
here the correct code.

That's very redundant. Your problem really is to map a [0..255] value to [0..255] logarithmically. If you need speed, you calculate the logarithmic transformation offline and store that results in a lookup table.

So something like this would be much faster / simpler:

Code:
//  ++++  curve section  +++++++
  speedfinalValue = lookupTable[analogReed(sensorspeedPin) >> 2]; //read the sensor and return the highest 8 bits.
  //  ++++  curve section  +++++++

lookupTable[] is also very easy to calculate: for sensor value 0..255, you want the lookupTable to return (255/log(255)) * log(sensor value), other than for sensor value 0, the lookupTable should return 0.

So the table should look like this (using natural base, not 10 base):

Code:
0
0
31
50
63
74
82
89
95
101
105
110
114
118
121
124
127
130
133
135
137
140
142
144
146
148
149
151
153
154
156
158
159
160
162
163
164
166
167
168
169
170
172
173
174
175
176
177
178
179
180
180
181
182
183
184
185
186
186
187
188
189
189
190
191
192
192
193
194
194
195
196
196
197
198
198
199
199
200
201
201
202
202
203
203
204
204
205
206
206
207
207
208
208
209
209
210
210
210
211
211
212
212
213
213
214
214
215
215
215
216
216
217
217
217
218
218
219
219
219
220
220
221
221
221
222
222
222
223
223
223
224
224
225
225
225
226
226
226
227
227
227
228
228
228
229
229
229
229
230
230
230
231
231
231
232
232
232
232
233
233
233
234
234
234
234
235
235
235
236
236
236
236
237
237
237
237
238
238
238
238
239
239
239
239
240
240
240
240
241
241
241
241
242
242
242
242
243
243
243
243
244
244
244
244
244
245
245
245
245
246
246
246
246
246
247
247
247
247
247
248
248
248
248
249
249
249
249
249
250
250
250
250
250
251
251
251
251
251
252
252
252
252
252
252
253
253
253
253
253
254
254
254
254
254
255

Logged

The Netherlands
Offline Offline
Sr. Member
****
Karma: 4
Posts: 330
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dhenry,

Thanks for your explanation.
We already use offline lookuptable filling.
The lookuptable is filled with data in a seperate function. "void fillLookupTable"
See the code in the response 120 from Rob.

I will post the full code as attachment now too.
Rob also said he liked to view the whole code.
Problem is it is so large now to place here in code tags.
Threrefor the snippets are less confusing...........? :-)

So I attach the last code I have as zip.
It is dirty as you can get from a low level programmer like me.
Could be faster in the end.........

Thanks, Paco

* slotracecontroller_305_ino.zip (6.39 KB - downloaded 14 times.)
Logged

Never to old to learn and I learn every day

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The lookuptable is filled with data in a seperate function.

Unless you have a mcu with lots of ram, that would be the wrong thing to do.
Logged

The Netherlands
Offline Offline
Sr. Member
****
Karma: 4
Posts: 330
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dhenry,

Currently use a Mega so enough Ram or am I mistaken.
An UNO or Nano would be on the edge of Free ram.

Paco



Logged

Never to old to learn and I learn every day

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It uses at least 256 bytes of ram, as coded.

It may not be an issue for your platform but in general, you want to store constant data in the rom.
Logged

The Netherlands
Offline Offline
Sr. Member
****
Karma: 4
Posts: 330
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You mean to write the lookuptable data everytime it changes in the EEProm and read it from there instead of the lookuptable using sRAM?

Paco
Logged

Never to old to learn and I learn every day

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13478
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use PROGMEM - to put the table in ROM - see reference section.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

The Netherlands
Offline Offline
Sr. Member
****
Karma: 4
Posts: 330
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rob, I read progmem reference but also memory section.

You mean to BURN the table in the flashrom?
What I understand this will only work if you have only one curve to use.
If that is the case it will not work?
During use of the controller the lookuptable will change by changing startspeed, X and Y pointvalue and if we use an real exponential curve the curveValue.

Paco
Logged

Never to old to learn and I learn every day

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13478
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


you are right, if the LUT changes runtime you cannot use PROGMEM.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: 1 ... 7 8 [9]   Go Up
Jump to: