configure sensors on FRDM KL46Z and send data through Serial port. Need host(PC) software to interact with. Sampling rate can vary by proper instruction

Dependencies:   EventFramework mbed

Committer:
xmnan
Date:
Sat Feb 15 07:52:46 2014 +0000
Revision:
0:2b49a387e831
original version.; Utilize EventFrameWork; sensors: MMA8451Q MAG3110 TSISensor lightSensor + analog input

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xmnan 0:2b49a387e831 1 #include "mbed.h"
xmnan 0:2b49a387e831 2 #include "TSISensor.h"
xmnan 0:2b49a387e831 3 #include "MMA8451Q.h"
xmnan 0:2b49a387e831 4 #include "MAG3110.h"
xmnan 0:2b49a387e831 5 #include "EventFramework/EventFramework.h"
xmnan 0:2b49a387e831 6 #include <cstdlib>
xmnan 0:2b49a387e831 7
xmnan 0:2b49a387e831 8 #define OFF 0
xmnan 0:2b49a387e831 9 #define ON 1
xmnan 0:2b49a387e831 10
xmnan 0:2b49a387e831 11 #define DEBUG
xmnan 0:2b49a387e831 12
xmnan 0:2b49a387e831 13 PwmOut rled(PTE29);
xmnan 0:2b49a387e831 14 PwmOut gled(PTD5);
xmnan 0:2b49a387e831 15
xmnan 0:2b49a387e831 16 Serial pc(USBTX, USBRX);
xmnan 0:2b49a387e831 17
xmnan 0:2b49a387e831 18 MMA8451Q acc51(PTE25, PTE24, 0x1D<<1);
xmnan 0:2b49a387e831 19 MAG3110 mag(PTE25, PTE24);
xmnan 0:2b49a387e831 20 AnalogIn lightSensor(PTE22);
xmnan 0:2b49a387e831 21 TSISensor tsi;
xmnan 0:2b49a387e831 22 AnalogIn sinewave(PTB1);
xmnan 0:2b49a387e831 23
xmnan 0:2b49a387e831 24 // labels for different data channel
xmnan 0:2b49a387e831 25 char MAG_X = 0x00;
xmnan 0:2b49a387e831 26 char MAG_Y = 0x01;
xmnan 0:2b49a387e831 27 char MAG_Z = 0x02;
xmnan 0:2b49a387e831 28 char MAG_H = 0x03;
xmnan 0:2b49a387e831 29 char ACC_X = 0x04;
xmnan 0:2b49a387e831 30 char ACC_Y = 0x05;
xmnan 0:2b49a387e831 31 char ACC_Z = 0x06;
xmnan 0:2b49a387e831 32 char LIT_X = 0x07;
xmnan 0:2b49a387e831 33 char TOU_X = 0x08;
xmnan 0:2b49a387e831 34 char SIN_X = 0x09;
xmnan 0:2b49a387e831 35
xmnan 0:2b49a387e831 36
xmnan 0:2b49a387e831 37 int MAG_STATUS = OFF;
xmnan 0:2b49a387e831 38 int ACCL_STATUS = OFF;
xmnan 0:2b49a387e831 39 int LIGHT_STATUS = OFF;
xmnan 0:2b49a387e831 40 int TOUCH_STATUS = OFF;
xmnan 0:2b49a387e831 41 int SINE_STATUS = OFF;
xmnan 0:2b49a387e831 42
xmnan 0:2b49a387e831 43 Timer t1;
xmnan 0:2b49a387e831 44 Timer t2;
xmnan 0:2b49a387e831 45 Timer t3;
xmnan 0:2b49a387e831 46 Timer t4;
xmnan 0:2b49a387e831 47 Timer t5;
xmnan 0:2b49a387e831 48
xmnan 0:2b49a387e831 49 //time threshold, equals to 1/sampling_rate
xmnan 0:2b49a387e831 50 int interval1 = 10000;
xmnan 0:2b49a387e831 51 int interval2 = 10000;
xmnan 0:2b49a387e831 52 int interval3 = 10000;
xmnan 0:2b49a387e831 53 int interval4 = 10000;
xmnan 0:2b49a387e831 54 int interval5 = 10000;
xmnan 0:2b49a387e831 55
xmnan 0:2b49a387e831 56 // framework creation with cooperative scheduling mechanism.
xmnan 0:2b49a387e831 57 EventFramework kernel(EventFramework::SCHED_VALUE_COOPERATIVE);
xmnan 0:2b49a387e831 58 // Events creation
xmnan 0:2b49a387e831 59 Event accl_Evt(0);
xmnan 0:2b49a387e831 60 Event mag_Evt(0);
xmnan 0:2b49a387e831 61 Event light_Evt(0);
xmnan 0:2b49a387e831 62 Event touch_Evt(0);
xmnan 0:2b49a387e831 63 Event sine_Evt(0);
xmnan 0:2b49a387e831 64 // EventHandlers creation
xmnan 0:2b49a387e831 65 EventHandler eh_accl(0);
xmnan 0:2b49a387e831 66 EventHandler eh_mag(0);
xmnan 0:2b49a387e831 67 EventHandler eh_light(0);
xmnan 0:2b49a387e831 68 EventHandler eh_touch(0);
xmnan 0:2b49a387e831 69 EventHandler eh_sine(0);
xmnan 0:2b49a387e831 70 // declaration of event dispatching functions that will be attached to previous EventHandlers
xmnan 0:2b49a387e831 71 EventDispatchingRoutine ev_accl_handle_func;
xmnan 0:2b49a387e831 72 EventDispatchingRoutine ev_mag_handle_func;
xmnan 0:2b49a387e831 73 EventDispatchingRoutine ev_light_handle_func;
xmnan 0:2b49a387e831 74 EventDispatchingRoutine ev_touch_handle_func;
xmnan 0:2b49a387e831 75 EventDispatchingRoutine ev_sine_handle_func;
xmnan 0:2b49a387e831 76
xmnan 0:2b49a387e831 77 int START = OFF;
xmnan 0:2b49a387e831 78
xmnan 0:2b49a387e831 79 void sendint(char label,int x){
xmnan 0:2b49a387e831 80 char *p = (char *)&x;
xmnan 0:2b49a387e831 81 pc.putc(label);
xmnan 0:2b49a387e831 82 pc.putc(*p);
xmnan 0:2b49a387e831 83 pc.putc(*(p+1));
xmnan 0:2b49a387e831 84 pc.putc(*(p+2));
xmnan 0:2b49a387e831 85 pc.putc(*(p+3));
xmnan 0:2b49a387e831 86 }
xmnan 0:2b49a387e831 87
xmnan 0:2b49a387e831 88 void sendfloat(char label,float x){
xmnan 0:2b49a387e831 89 char *p = (char *)&x;
xmnan 0:2b49a387e831 90 pc.putc(label);
xmnan 0:2b49a387e831 91 pc.putc(*p);
xmnan 0:2b49a387e831 92 pc.putc(*(p+1));
xmnan 0:2b49a387e831 93 pc.putc(*(p+2));
xmnan 0:2b49a387e831 94 pc.putc(*(p+3));
xmnan 0:2b49a387e831 95 }
xmnan 0:2b49a387e831 96
xmnan 0:2b49a387e831 97 void calXY() //magnetometer calibration: finding max and min of X, Y axis
xmnan 0:2b49a387e831 98 {
xmnan 0:2b49a387e831 99 int tempXmax, tempXmin, tempYmax, tempYmin, newX, newY;
xmnan 0:2b49a387e831 100
xmnan 0:2b49a387e831 101 rled = ON;
xmnan 0:2b49a387e831 102
xmnan 0:2b49a387e831 103 printf("Waiting for initial press\n");
xmnan 0:2b49a387e831 104 // Wait for slider to be pressed
xmnan 0:2b49a387e831 105 while( tsi.readDistance() == 0 ) {
xmnan 0:2b49a387e831 106 rled = ON;
xmnan 0:2b49a387e831 107 wait(0.2);
xmnan 0:2b49a387e831 108 rled = OFF;
xmnan 0:2b49a387e831 109 wait(0.2);
xmnan 0:2b49a387e831 110 }
xmnan 0:2b49a387e831 111
xmnan 0:2b49a387e831 112 printf("Waiting for release\n");
xmnan 0:2b49a387e831 113
xmnan 0:2b49a387e831 114 // Wait for release
xmnan 0:2b49a387e831 115 while( tsi.readDistance() != 0 ) {
xmnan 0:2b49a387e831 116 rled = OFF;
xmnan 0:2b49a387e831 117 wait(0.2);
xmnan 0:2b49a387e831 118 rled = ON;
xmnan 0:2b49a387e831 119 wait(0.2);
xmnan 0:2b49a387e831 120 }
xmnan 0:2b49a387e831 121 rled = OFF;
xmnan 0:2b49a387e831 122 wait(0.5);
xmnan 0:2b49a387e831 123
xmnan 0:2b49a387e831 124 printf("Rotate\n");
xmnan 0:2b49a387e831 125
xmnan 0:2b49a387e831 126 tempXmax = tempXmin = mag.readVal(MAG_OUT_X_MSB);
xmnan 0:2b49a387e831 127 tempYmax = tempYmin = mag.readVal(MAG_OUT_Y_MSB);
xmnan 0:2b49a387e831 128
xmnan 0:2b49a387e831 129 while(tsi.readDistance() == 0) {
xmnan 0:2b49a387e831 130 gled = ON;
xmnan 0:2b49a387e831 131 wait(0.1);
xmnan 0:2b49a387e831 132 gled = OFF;
xmnan 0:2b49a387e831 133 wait(0.1);
xmnan 0:2b49a387e831 134 newX = mag.readVal(MAG_OUT_X_MSB);
xmnan 0:2b49a387e831 135 newY = mag.readVal(MAG_OUT_Y_MSB);
xmnan 0:2b49a387e831 136 if (newX > tempXmax) tempXmax = newX;
xmnan 0:2b49a387e831 137 if (newX < tempXmin) tempXmin = newX;
xmnan 0:2b49a387e831 138 if (newY > tempYmax) tempYmax = newY;
xmnan 0:2b49a387e831 139 if (newY < tempYmin) tempYmin = newY;
xmnan 0:2b49a387e831 140 }
xmnan 0:2b49a387e831 141
xmnan 0:2b49a387e831 142 mag.setCalibration( tempXmin, tempXmax, tempYmin, tempYmax );
xmnan 0:2b49a387e831 143
xmnan 0:2b49a387e831 144 // Wait for release
xmnan 0:2b49a387e831 145 while( tsi.readDistance() != 0 ) {
xmnan 0:2b49a387e831 146 gled = OFF;
xmnan 0:2b49a387e831 147 wait(0.2);
xmnan 0:2b49a387e831 148 gled = ON;
xmnan 0:2b49a387e831 149 wait(0.2);
xmnan 0:2b49a387e831 150 }
xmnan 0:2b49a387e831 151 gled = OFF;
xmnan 0:2b49a387e831 152 wait(1.0);
xmnan 0:2b49a387e831 153 }
xmnan 0:2b49a387e831 154
xmnan 0:2b49a387e831 155 uint32_t ev_accl_handle_func(void* me, void* args){
xmnan 0:2b49a387e831 156 float temp_x = acc51.getAccX();
xmnan 0:2b49a387e831 157 float temp_y = acc51.getAccY();
xmnan 0:2b49a387e831 158 float temp_z = acc51.getAccZ();
xmnan 0:2b49a387e831 159 __disable_irq();
xmnan 0:2b49a387e831 160 sendfloat(ACC_X,temp_x);
xmnan 0:2b49a387e831 161 sendfloat(ACC_Y,temp_y);
xmnan 0:2b49a387e831 162 sendfloat(ACC_Z,temp_z);
xmnan 0:2b49a387e831 163 __enable_irq();
xmnan 0:2b49a387e831 164 }
xmnan 0:2b49a387e831 165 uint32_t ev_mag_handle_func(void* me, void* args){
xmnan 0:2b49a387e831 166 int temp_x = 0, temp_y = 0, temp_z = 0;
xmnan 0:2b49a387e831 167 float temp_h = mag.getHeading();
xmnan 0:2b49a387e831 168 mag.getValues(&temp_x, &temp_y, &temp_z);
xmnan 0:2b49a387e831 169 __disable_irq();
xmnan 0:2b49a387e831 170 sendint(MAG_X,temp_x);
xmnan 0:2b49a387e831 171 sendint(MAG_Y,temp_y);
xmnan 0:2b49a387e831 172 sendint(MAG_Z,temp_z);
xmnan 0:2b49a387e831 173 sendfloat(MAG_H,temp_h);
xmnan 0:2b49a387e831 174 __enable_irq();
xmnan 0:2b49a387e831 175 }
xmnan 0:2b49a387e831 176 uint32_t ev_light_handle_func(void* me, void* args){
xmnan 0:2b49a387e831 177 float temp_x = lightSensor;
xmnan 0:2b49a387e831 178 __disable_irq();
xmnan 0:2b49a387e831 179 sendfloat(LIT_X,temp_x);
xmnan 0:2b49a387e831 180 __enable_irq();
xmnan 0:2b49a387e831 181 }
xmnan 0:2b49a387e831 182 uint32_t ev_touch_handle_func(void* me, void* args){
xmnan 0:2b49a387e831 183 float temp_x = tsi.readPercentage();;
xmnan 0:2b49a387e831 184 __disable_irq();
xmnan 0:2b49a387e831 185 sendfloat(TOU_X,temp_x);
xmnan 0:2b49a387e831 186 __enable_irq();
xmnan 0:2b49a387e831 187 }
xmnan 0:2b49a387e831 188 uint32_t ev_sine_handle_func(void* me, void* args){
xmnan 0:2b49a387e831 189 float temp_x = sinewave.read();;
xmnan 0:2b49a387e831 190 __disable_irq();
xmnan 0:2b49a387e831 191 sendfloat(SIN_X,temp_x);
xmnan 0:2b49a387e831 192 __enable_irq();
xmnan 0:2b49a387e831 193 }
xmnan 0:2b49a387e831 194 void pc_command(){
xmnan 0:2b49a387e831 195 kernel.SaveContext();
xmnan 0:2b49a387e831 196 char command = pc.getc();
xmnan 0:2b49a387e831 197 float sr;
xmnan 0:2b49a387e831 198 char temp[4];
xmnan 0:2b49a387e831 199
xmnan 0:2b49a387e831 200 switch(command)
xmnan 0:2b49a387e831 201 {
xmnan 0:2b49a387e831 202 case 0xEE : // configuration or reconfiguration header
xmnan 0:2b49a387e831 203
xmnan 0:2b49a387e831 204 command = pc.getc();
xmnan 0:2b49a387e831 205 if (command == 0x01){ // check the status of magnetometer
xmnan 0:2b49a387e831 206 MAG_STATUS = ON;// turn it on
xmnan 0:2b49a387e831 207 temp[0] = pc.getc();
xmnan 0:2b49a387e831 208 temp[1] = pc.getc();
xmnan 0:2b49a387e831 209 temp[2] = pc.getc();
xmnan 0:2b49a387e831 210 temp[3] = pc.getc();
xmnan 0:2b49a387e831 211 sr = *(float*)temp;//sampling rate
xmnan 0:2b49a387e831 212 interval1 =(int) 1/sr *1000;//threshold
xmnan 0:2b49a387e831 213 t1.reset();//timer reset
xmnan 0:2b49a387e831 214 }
xmnan 0:2b49a387e831 215 else{
xmnan 0:2b49a387e831 216 MAG_STATUS = OFF;//turn it off
xmnan 0:2b49a387e831 217 t1.stop();
xmnan 0:2b49a387e831 218 }
xmnan 0:2b49a387e831 219 command = pc.getc();
xmnan 0:2b49a387e831 220 if (command == 0x01){ // check the status of accelerometer
xmnan 0:2b49a387e831 221 ACCL_STATUS = ON;
xmnan 0:2b49a387e831 222 temp[0] = pc.getc();
xmnan 0:2b49a387e831 223 temp[1] = pc.getc();
xmnan 0:2b49a387e831 224 temp[2] = pc.getc();
xmnan 0:2b49a387e831 225 temp[3] = pc.getc();
xmnan 0:2b49a387e831 226 sr = *(float*)temp;
xmnan 0:2b49a387e831 227 interval2 =(int) 1/sr *1000;
xmnan 0:2b49a387e831 228 t2.reset();
xmnan 0:2b49a387e831 229 }
xmnan 0:2b49a387e831 230 else{
xmnan 0:2b49a387e831 231 ACCL_STATUS = OFF;
xmnan 0:2b49a387e831 232 t2.stop();
xmnan 0:2b49a387e831 233 }
xmnan 0:2b49a387e831 234 command = pc.getc();
xmnan 0:2b49a387e831 235 if (command == 0x01){ // check the status of the light sensor
xmnan 0:2b49a387e831 236 LIGHT_STATUS = ON;
xmnan 0:2b49a387e831 237 temp[0] = pc.getc();
xmnan 0:2b49a387e831 238 temp[1] = pc.getc();
xmnan 0:2b49a387e831 239 temp[2] = pc.getc();
xmnan 0:2b49a387e831 240 temp[3] = pc.getc();
xmnan 0:2b49a387e831 241 sr = *(float*)temp;
xmnan 0:2b49a387e831 242 interval3 =(int) 1/sr *1000;
xmnan 0:2b49a387e831 243 t3.reset();
xmnan 0:2b49a387e831 244 }
xmnan 0:2b49a387e831 245 else{
xmnan 0:2b49a387e831 246 LIGHT_STATUS = OFF;
xmnan 0:2b49a387e831 247 t3.stop();
xmnan 0:2b49a387e831 248 }
xmnan 0:2b49a387e831 249 command = pc.getc();
xmnan 0:2b49a387e831 250 if (command == 0x01){ // check the status of the touch sensor
xmnan 0:2b49a387e831 251 TOUCH_STATUS = ON;
xmnan 0:2b49a387e831 252 temp[0] = pc.getc();
xmnan 0:2b49a387e831 253 temp[1] = pc.getc();
xmnan 0:2b49a387e831 254 temp[2] = pc.getc();
xmnan 0:2b49a387e831 255 temp[3] = pc.getc();
xmnan 0:2b49a387e831 256 sr = *(float*)temp;
xmnan 0:2b49a387e831 257 interval4 =(int) 1/sr *1000;
xmnan 0:2b49a387e831 258 t4.reset();
xmnan 0:2b49a387e831 259 }
xmnan 0:2b49a387e831 260 else{
xmnan 0:2b49a387e831 261 TOUCH_STATUS = OFF;
xmnan 0:2b49a387e831 262 t4.stop();
xmnan 0:2b49a387e831 263 }
xmnan 0:2b49a387e831 264 command = pc.getc();
xmnan 0:2b49a387e831 265 if (command == 0x01){ // check the status of the sine wave receiver
xmnan 0:2b49a387e831 266 SINE_STATUS = ON;
xmnan 0:2b49a387e831 267 temp[0] = pc.getc();
xmnan 0:2b49a387e831 268 temp[1] = pc.getc();
xmnan 0:2b49a387e831 269 temp[2] = pc.getc();
xmnan 0:2b49a387e831 270 temp[3] = pc.getc();
xmnan 0:2b49a387e831 271 sr = *(float*)temp;
xmnan 0:2b49a387e831 272 interval5 =(int) 1/sr *1000;
xmnan 0:2b49a387e831 273 t5.reset();
xmnan 0:2b49a387e831 274 }
xmnan 0:2b49a387e831 275 else{
xmnan 0:2b49a387e831 276 SINE_STATUS = OFF;
xmnan 0:2b49a387e831 277 t5.stop();
xmnan 0:2b49a387e831 278 }
xmnan 0:2b49a387e831 279 START = ON;
xmnan 0:2b49a387e831 280 rled = ON;
xmnan 0:2b49a387e831 281 break;
xmnan 0:2b49a387e831 282 }
xmnan 0:2b49a387e831 283 kernel.RestoreContext();
xmnan 0:2b49a387e831 284 }
xmnan 0:2b49a387e831 285
xmnan 0:2b49a387e831 286 int main()
xmnan 0:2b49a387e831 287 {
xmnan 0:2b49a387e831 288 // events must be registered into the framework
xmnan 0:2b49a387e831 289 kernel.AddEvent(&mag_Evt);
xmnan 0:2b49a387e831 290 kernel.AddEvent(&accl_Evt);
xmnan 0:2b49a387e831 291 kernel.AddEvent(&light_Evt);
xmnan 0:2b49a387e831 292 kernel.AddEvent(&touch_Evt);
xmnan 0:2b49a387e831 293 kernel.AddEvent(&sine_Evt);
xmnan 0:2b49a387e831 294
xmnan 0:2b49a387e831 295 eh_mag.Attach(&ev_mag_handle_func);
xmnan 0:2b49a387e831 296 eh_accl.Attach(&ev_accl_handle_func);
xmnan 0:2b49a387e831 297 eh_light.Attach(&ev_light_handle_func);
xmnan 0:2b49a387e831 298 eh_touch.Attach(&ev_touch_handle_func);
xmnan 0:2b49a387e831 299 eh_sine.Attach(&ev_sine_handle_func);
xmnan 0:2b49a387e831 300
xmnan 0:2b49a387e831 301 // handlers are registered into the kernel to listen to specific events. [eh1] listens to [ev1], [eh2] listens to [ev2].
xmnan 0:2b49a387e831 302 kernel.AddEventListener(&mag_Evt, &eh_mag);
xmnan 0:2b49a387e831 303 kernel.AddEventListener(&accl_Evt, &eh_accl);
xmnan 0:2b49a387e831 304 kernel.AddEventListener(&light_Evt, &eh_light);
xmnan 0:2b49a387e831 305 kernel.AddEventListener(&touch_Evt, &eh_touch);
xmnan 0:2b49a387e831 306 kernel.AddEventListener(&sine_Evt, &eh_sine);
xmnan 0:2b49a387e831 307 calXY();
xmnan 0:2b49a387e831 308 pc.attach(&pc_command);
xmnan 0:2b49a387e831 309
xmnan 0:2b49a387e831 310 while(START == OFF){
xmnan 0:2b49a387e831 311 pc.putc(0xFF);
xmnan 0:2b49a387e831 312 }
xmnan 0:2b49a387e831 313 pc.putc(0xFE);
xmnan 0:2b49a387e831 314
xmnan 0:2b49a387e831 315 t1.start();
xmnan 0:2b49a387e831 316 t2.start();
xmnan 0:2b49a387e831 317 t3.start();
xmnan 0:2b49a387e831 318 t4.start();
xmnan 0:2b49a387e831 319 t5.start();
xmnan 0:2b49a387e831 320 // the event-driven kernel starts its operation.
xmnan 0:2b49a387e831 321 while(1) {
xmnan 0:2b49a387e831 322 kernel.Schedule();
xmnan 0:2b49a387e831 323 if (MAG_STATUS == ON){
xmnan 0:2b49a387e831 324 if (t1.read_ms()>interval1){
xmnan 0:2b49a387e831 325 kernel.PublishEvent(&mag_Evt, 0);
xmnan 0:2b49a387e831 326 t1.reset();
xmnan 0:2b49a387e831 327 }
xmnan 0:2b49a387e831 328 }
xmnan 0:2b49a387e831 329 if (ACCL_STATUS == ON){
xmnan 0:2b49a387e831 330 if (t2.read_ms()>interval2){
xmnan 0:2b49a387e831 331 kernel.PublishEvent(&accl_Evt, 0);
xmnan 0:2b49a387e831 332 t2.reset();
xmnan 0:2b49a387e831 333 }
xmnan 0:2b49a387e831 334 }
xmnan 0:2b49a387e831 335 if (LIGHT_STATUS == ON){
xmnan 0:2b49a387e831 336 if (t3.read_ms()>interval3){
xmnan 0:2b49a387e831 337 kernel.PublishEvent(&light_Evt, 0);
xmnan 0:2b49a387e831 338 t3.reset();
xmnan 0:2b49a387e831 339 }
xmnan 0:2b49a387e831 340 }
xmnan 0:2b49a387e831 341 if (TOUCH_STATUS == ON){
xmnan 0:2b49a387e831 342 if (t4.read_ms()>interval4){
xmnan 0:2b49a387e831 343 kernel.PublishEvent(&touch_Evt, 0);
xmnan 0:2b49a387e831 344 t4.reset();
xmnan 0:2b49a387e831 345 }
xmnan 0:2b49a387e831 346 }
xmnan 0:2b49a387e831 347 if (SINE_STATUS == ON){
xmnan 0:2b49a387e831 348 if (t5.read_ms()>interval5){
xmnan 0:2b49a387e831 349 kernel.PublishEvent(&sine_Evt, 0);
xmnan 0:2b49a387e831 350 t5.reset();
xmnan 0:2b49a387e831 351 }
xmnan 0:2b49a387e831 352 }
xmnan 0:2b49a387e831 353 }
xmnan 0:2b49a387e831 354 }