summaryrefslogtreecommitdiff
path: root/apps/plugins/resistor.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/resistor.c')
-rw-r--r--apps/plugins/resistor.c1150
1 files changed, 1150 insertions, 0 deletions
diff --git a/apps/plugins/resistor.c b/apps/plugins/resistor.c
new file mode 100644
index 0000000000..28e4ae85b8
--- /dev/null
+++ b/apps/plugins/resistor.c
@@ -0,0 +1,1150 @@
1/* === Rockbox Resistor code/value calculator ===
2[insert relevant/useful information here]
3TODO:
4[ ] Own numeric keypad
5*/
6
7#include "plugin.h"
8#include "lib/display_text.h"
9#include "lib/pluginlib_actions.h"
10#include "lib/picture.h"
11#include "lib/helper.h"
12
13/* Defining player-specific constants */
14
15#if defined(HAVE_LCD_COLOR)
16#define RESISTOR_BMP_X 0
17/* The BMPs are now the exact width of the screen */
18
19#if LCD_WIDTH >= 320 && LCD_HEIGHT >= 240 /* iPod video or larger */
20#define RESISTOR_BMP_Y 3
21
22#elif LCD_WIDTH >= 240 && LCD_HEIGHT >= 320 /* Onda, mostly */
23#define RESISTOR_BMP_Y 3
24
25#elif LCD_WIDTH >= 220 && LCD_HEIGHT >= 176 /* Fuze or larger */
26#define RESISTOR_BMP_Y 15
27
28#elif LCD_WIDTH >= 176 && LCD_HEIGHT >= 220 /* e200 or larger */
29#define RESISTOR_BMP_Y 11
30
31#elif LCD_WIDTH >= 176 && LCD_HEIGHT >= 132 /* ipod nano or larger */
32#define RESISTOR_BMP_Y 7
33
34#elif LCD_WIDTH >= 160 && LCD_HEIGHT >= 128 /* H10 or larger */
35#define RESISTOR_BMP_Y 3
36
37#elif LCD_WIDTH >= 128 && LCD_HEIGHT >= 128 /* GoGear */
38#define RESISTOR_BMP_Y 3
39
40#elif LCD_WIDTH >= 132 && LCD_HEIGHT >= 80 /* c200 */
41#define RESISTOR_BMP_Y 0
42/* And along with the tiny screen comes a whole bunch of exceptions */
43
44#endif /* HAVE_LCD_COLOR */
45
46#else
47
48#define USE_TEXT_ONLY
49#endif
50
51#ifdef USE_TEXT_ONLY
52#define resistance_val_x 0
53#define resistance_val_y 1
54
55#if LCD_HEIGHT <= 64
56#define total_resistance_str_x 0
57#define total_resistance_str_y 17
58#define tolerance_str_x 0
59#define tolerance_str_y 32
60#define r_to_c_out_str_y (total_resistance_str_y + 15)
61#define r_to_c_out_str_x 1
62#else
63#define total_resistance_str_x 0
64#define total_resistance_str_y 25
65#define tolerance_str_x 0
66#define tolerance_str_y 45
67#define r_to_c_out_str_x 0
68#define r_to_c_out_str_y 45
69#endif /* LCD_HEIGHT = <= 64 */
70
71#else /* USE_TEXT_ONLY */
72/* (below is for color targets */
73
74
75#include "pluginbitmaps/resistor.h"
76
77#if LCD_WIDTH == 132 && LCD_HEIGHT == 80
78/* Proboably not the best solution */
79/* Special for the c200 */
80#define band_width 5
81#define band_height 16
82
83#define first_band_x 50
84#define second_band_x 60
85#define third_band_x 70
86#define fourth_band_x 80
87#define universal_y 2
88
89#else /* LCD_WIDTH == 132 && LCD_HEIGHT == 80 */
90/* Everything else */
91
92#define band_width (BMPWIDTH_resistor/15)
93#define band_height (BMPHEIGHT_resistor*9/10)
94
95#define first_band_x (BMPWIDTH_resistor/4 + RESISTOR_BMP_X - band_width/2)
96#define second_band_x (3*BMPWIDTH_resistor/8 + RESISTOR_BMP_X - band_width/2)
97#define third_band_x (BMPWIDTH_resistor/2 + RESISTOR_BMP_X - band_width/2)
98#define fourth_band_x (3*BMPWIDTH_resistor/4 + RESISTOR_BMP_X - band_width/2)
99#define universal_y (RESISTOR_BMP_Y+(BMPHEIGHT_resistor)/2 - band_height/2)
100
101#endif /* LCD_WIDTH == 132 && LCD_HEIGHT == 80 */
102
103#if LCD_HEIGHT <= 128
104#define total_resistance_str_x 1
105#define total_resistance_str_y (BMPHEIGHT_resistor + RESISTOR_BMP_Y + 3)
106
107#define tolerance_str_x 1
108#define tolerance_str_y total_resistance_str_y + 20
109#define resistance_val_x 1
110#define resistance_val_y total_resistance_str_y + 20
111#define r_to_c_out_str_x 1
112#define r_to_c_out_str_y total_resistance_str_y + 30
113
114#elif LCD_WIDTH == 132 && LCD_HEIGHT == 80 /* Special for the c200 */
115#define total_resistance_str_x 0
116#define total_resistance_str_y BMPHEIGHT_resistor + 1
117
118#define tolerance_str_x 0
119#define tolerance_str_y total_resistance_str_y + 8
120#define resistance_val_x 0
121#define resistance_val_y tolerance_resistance_str_y + 8
122#define r_to_c_out_str_x 0
123#define r_to_c_out_str_y tolerance_resistance_str_y + 16
124
125#else /* LCD_HEIGHT <= 128 */
126#define total_resistance_str_x (LCD_WIDTH/14)
127#define total_resistance_str_y (2*RESISTOR_BMP_Y + BMPHEIGHT_resistor)
128
129#define tolerance_str_x (LCD_WIDTH/14)
130#define tolerance_str_y (total_resistance_str_y + 15)
131#define resistance_val_x (LCD_WIDTH/14)
132#define resistance_val_y (total_resistance_str_y + 15)
133#define r_to_c_out_str_x (LCD_WIDTH/14)
134#define r_to_c_out_str_y (total_resistance_str_y + 25)
135/* tolerance_str and resistance_val will never be shown at the same time */
136
137#endif /* LCD_HEIGHT <= 128 */
138
139#endif /* USE_TEXT_ONLY */
140
141enum color {
142 RES_BLACK,
143 RES_BROWN,
144 RES_RED,
145 RES_ORANGE,
146 RES_YELLOW,
147 RES_GREEN,
148 RES_BLUE,
149 RES_VIOLET,
150 RES_GREY,
151 RES_WHITE,
152 RES_GOLD,
153 RES_SILVER,
154 RES_NONE,
155};
156
157int common_values[] = { 0, 1, 10, 15, 22, 27, 33, 39, 47, 51, 68, 82 };
158int power_ratings[] = { 125, 250, 500, 1000, 2000, 3000, 5000, 10000, 50000 };
159/* All in mW */
160
161#ifndef LCD_RGBPACK
162/* Warning: dirty kludge */
163#define LCD_RGBPACK(x,y,z) 0
164#endif
165
166struct band_data
167{
168 enum color color;
169 char *name;
170 int color_value;
171 int resistance_value;
172 int multiplier;
173 char *unit;
174 int tolerance;
175} band_data[] =
176{
177 { RES_BLACK, "Black", LCD_RGBPACK(0, 0, 0), 0, 100, "Ohms",-1 },
178 { RES_BROWN, "Brown", LCD_RGBPACK(118, 78, 0), 1, 1000, "Ohms", 1 },
179 { RES_RED, "Red", LCD_RGBPACK(255, 0, 0), 2, 10000, "KOhms", 2 },
180 { RES_ORANGE, "Orange", LCD_RGBPACK(255, 199, 76), 3, 100, "KOhms",-1 },
181 { RES_YELLOW, "Yellow", LCD_RGBPACK(255, 255, 0), 4, 1000, "KOhms",-1 },
182 { RES_GREEN, "Green", LCD_RGBPACK(0, 128, 0), 5, 10000, "MOhms",-1 },
183 { RES_BLUE, "Blue", LCD_RGBPACK(0, 0, 255), 6, 100, "MOhms",-1 },
184 { RES_VIOLET, "Violet", LCD_RGBPACK(153, 51, 255), 7, -1, 0, -1 },
185 { RES_GREY, "Grey", LCD_RGBPACK(192, 192, 192), 8, -1, 0, -1 },
186 { RES_WHITE, "White", LCD_RGBPACK(255, 255, 255), 9, -1, 0, -1 },
187 { RES_GOLD, "Gold", LCD_RGBPACK(146, 146, 0), -1, 1, "Ohms", 5 },
188 { RES_SILVER, "Silver", LCD_RGBPACK(213, 213, 213),-1, 10, "Ohms", 10 },
189 { RES_NONE, "[None]", -1 ,-1, -1, 0, 20 }
190};
191
192char *unit_abbrev;
193char tolerance_str [14];
194char power_rating_str [10];
195int r_to_c_first_band;
196int r_to_c_second_band;
197int r_to_c_third_band;
198
199char str [4][7];
200
201void get_power_rating_str(int in_rating)
202{
203switch(in_rating) {
204 case 125:
205 rb->snprintf(power_rating_str, sizeof(power_rating_str), "1/8 Watt");
206 break;
207 case 250:
208 rb->snprintf(power_rating_str, sizeof(power_rating_str), "1/4 Watt");
209 break;
210 case 500:
211 rb->snprintf(power_rating_str, sizeof(power_rating_str), "1/2 Watt");
212 break;
213 case 1000:
214 rb->snprintf(power_rating_str, sizeof(power_rating_str), "1 Watt");
215 break;
216 case 2000:
217 rb->snprintf(power_rating_str, sizeof(power_rating_str), "2 Watt");
218 break;
219 case 3000:
220 rb->snprintf(power_rating_str, sizeof(power_rating_str), "3 Watt");
221 break;
222 case 5000:
223 rb->snprintf(power_rating_str, sizeof(power_rating_str), "5 Watt");
224 break;
225 case 10000:
226 rb->snprintf(power_rating_str, sizeof(power_rating_str), "10 Watt");
227 break;
228 case 500000:
229 rb->snprintf(power_rating_str, sizeof(power_rating_str), "50 Watt");
230 break;
231 }
232}
233
234int get_power_ten(int in_val)
235{
236 int power = 0;
237 if(in_val <= 9 && in_val >= 0) { power = 0; }
238 else if(in_val <= 99 && in_val >= 10) {power = 1;}
239 else if(in_val <= 999 && in_val >= 100) {power = 2;}
240 else if(in_val <= 9999 && in_val >= 1000) {power = 3;}
241 else if(in_val <= 99999 && in_val >= 10000) {power = 4;}
242 else if(in_val <= 999999 && in_val >= 100000) {power = 5;}
243 else if(in_val <= 9999999 && in_val >= 1000000) {power = 6;}
244 return power;
245}
246
247int powi(int num, int exp)
248{
249 int i, product = 1;
250 for (i = 0; i < exp; i++) {
251 product *= num; }
252
253 return product;
254}
255
256enum color get_band_rtoc(int in_val)
257{
258 int return_color = 0;
259 switch(in_val) {
260 case 0:
261 return_color = RES_BLACK;
262 break;
263 case 1:
264 return_color = RES_BROWN;
265 break;
266 case 2:
267 return_color = RES_RED;
268 break;
269 case 3:
270 return_color = RES_ORANGE;
271 break;
272 case 4:
273 return_color = RES_YELLOW;
274 break;
275 case 5:
276 return_color = RES_GREEN;
277 break;
278 case 6:
279 return_color = RES_BLUE;
280 break;
281 case 7:
282 return_color = RES_VIOLET;
283 break;
284 case 8:
285 return_color = RES_GREY;
286 break;
287 case 9:
288 return_color = RES_WHITE;
289 break;
290 }
291 return return_color;
292}
293
294void get_tolerance_str(enum color color)
295{
296 rb->snprintf(tolerance_str, sizeof(tolerance_str), "%d%% tolerance",
297 band_data[color].tolerance);
298}
299
300void draw_resistor_text(enum color firstband_color,
301 enum color secondband_color,
302 enum color thirdband_color,
303 enum color fourthband_color)
304{
305 char resistance_vals_str[64];
306 rb->snprintf(resistance_vals_str, sizeof(resistance_vals_str),
307 "%s - %s - %s - %s", band_data[firstband_color].name,
308 band_data[secondband_color].name,
309 band_data[thirdband_color].name,
310 band_data[fourthband_color].name);
311 #if LCD_HEIGHT == 80 /* c200 exception */
312 rb->lcd_putsxy(resistance_val_x, resistance_val_y-12, resistance_vals_str);
313 #else /* everything else */
314 rb->lcd_putsxy(resistance_val_x, resistance_val_y, resistance_vals_str);
315 #endif
316 rb->lcd_update();
317}
318
319#ifndef USE_TEXT_ONLY
320void draw_resistor(enum color firstband_color,
321 enum color secondband_color,
322 enum color thirdband_color,
323 enum color fourthband_color)
324{
325 rb->lcd_clear_display();
326 rb->lcd_bitmap_transparent(resistor, RESISTOR_BMP_X, RESISTOR_BMP_Y,
327 BMPWIDTH_resistor, BMPHEIGHT_resistor);
328
329 if(firstband_color != RES_NONE) {
330 rb->lcd_set_foreground(band_data[firstband_color].color_value);
331 rb->lcd_fillrect(first_band_x, universal_y, band_width, band_height);
332 } else {
333 rb->lcd_set_foreground(LCD_BLACK);
334 rb->lcd_drawrect(first_band_x, universal_y, band_width, band_height);
335 }
336
337 if(secondband_color != RES_NONE) {
338 rb->lcd_set_foreground(band_data[secondband_color].color_value);
339 rb->lcd_fillrect(second_band_x, universal_y, band_width, band_height);
340 } else {
341 rb->lcd_set_foreground(LCD_BLACK);
342 rb->lcd_drawrect(second_band_x, universal_y, band_width, band_height);
343 }
344
345 if(thirdband_color != RES_NONE) {
346 rb->lcd_set_foreground(band_data[thirdband_color].color_value);
347 rb->lcd_fillrect(third_band_x, universal_y, band_width, band_height);
348 } else {
349 rb->lcd_set_foreground(LCD_BLACK);
350 rb->lcd_drawrect(third_band_x, universal_y, band_width, band_height);
351 }
352
353 if(fourthband_color != RES_NONE) {
354 rb->lcd_set_foreground(band_data[fourthband_color].color_value);
355 rb->lcd_fillrect(fourth_band_x, universal_y, band_width, band_height);
356 } else {
357 rb->lcd_set_foreground(LCD_BLACK);
358 rb->lcd_drawrect(fourth_band_x, universal_y, band_width, band_height);
359 }
360
361 rb->lcd_set_foreground(LCD_WHITE);
362
363 rb->lcd_update();
364 return;
365}
366#else
367
368void draw_resistor(enum color firstband_color,
369 enum color secondband_color,
370 enum color thirdband_color,
371 enum color fourthband_color)
372{
373 char resistance_vals_str[64];
374 rb->snprintf(resistance_vals_str, sizeof(resistance_vals_str),
375 "%s - %s - %s - %s", band_data[firstband_color].name,
376 band_data[secondband_color].name,
377 band_data[thirdband_color].name,
378 band_data[fourthband_color].name);
379 rb->lcd_clear_display();
380 rb->lcd_puts_scroll(resistance_val_x, resistance_val_y, resistance_vals_str);
381 rb->lcd_update();
382}
383#endif
384
385int calculate_resistance(enum color first_band,
386 enum color second_band,
387 enum color third_band)
388{
389 int tens = band_data[first_band].resistance_value;
390 int units = band_data[second_band].resistance_value;
391 int multiplier = band_data[third_band].multiplier;
392 int total_resistance_centiunits = (10 * tens + units ) * multiplier;
393
394 if(total_resistance_centiunits == 100000) {
395 total_resistance_centiunits /= 1000; }
396 /* Kludge, I know, but it fixes the '1000 KOhms' issue */
397
398 unit_abbrev = band_data[third_band].unit;
399
400 return total_resistance_centiunits;
401}
402
403enum color do_first_band_menu(void)
404{
405 int band_selection = 0;
406 enum color band_color_selection = 0;
407
408 MENUITEM_STRINGLIST(colors_menu_first, "First band colour:", NULL,
409 "Black", "Brown", "Red", "Orange", "Yellow",
410 "Green", "Blue", "Violet", "Grey", "White");
411 band_selection = rb->do_menu(&colors_menu_first, &band_selection, NULL,
412 false);
413 switch(band_selection) {
414 case 0: /* Black */
415 band_color_selection = RES_BLACK;
416 break;
417 case 1: /* Brown */
418 band_color_selection = RES_BROWN;
419 break;
420 case 2: /* Red */
421 band_color_selection = RES_RED;
422 break;
423 case 3: /* Orange */
424 band_color_selection = RES_ORANGE;
425 break;
426 case 4: /* Yellow */
427 band_color_selection = RES_YELLOW;
428 break;
429 case 5: /* Green */
430 band_color_selection = RES_GREEN;
431 break;
432 case 6: /* Blue */
433 band_color_selection = RES_BLUE;
434 break;
435 case 7: /* Violet */
436 band_color_selection = RES_VIOLET;
437 break;
438 case 8: /* Grey */
439 band_color_selection = RES_GREY;
440 break;
441 case 9: /* White */
442 band_color_selection = RES_WHITE;
443 break;
444 }
445 return band_color_selection;
446}
447
448enum color do_second_band_menu(void)
449{
450 int band_selection = 0;
451 enum color band_color_selection = 0;
452
453 MENUITEM_STRINGLIST(colors_menu_second, "Second band colour:", NULL,
454 "Black", "Brown", "Red", "Orange", "Yellow",
455 "Green", "Blue", "Violet", "Grey", "White");
456 band_selection = rb->do_menu(&colors_menu_second, &band_selection, NULL,
457 false);
458 switch(band_selection) {
459 case 0: /* Black */
460 band_color_selection = RES_BLACK;
461 break;
462 case 1: /* Brown */
463 band_color_selection = RES_BROWN;
464 break;
465 case 2: /* Red */
466 band_color_selection = RES_RED;
467 break;
468 case 3: /* Orange */
469 band_color_selection = RES_ORANGE;
470 break;
471 case 4: /* Yellow */
472 band_color_selection = RES_YELLOW;
473 break;
474 case 5: /* Green */
475 band_color_selection = RES_GREEN;
476 break;
477 case 6: /* Blue */
478 band_color_selection = RES_BLUE;
479 break;
480 case 7: /* Violet */
481 band_color_selection = RES_VIOLET;
482 break;
483 case 8: /* Grey */
484 band_color_selection = RES_GREY;
485 break;
486 case 9: /* White */
487 band_color_selection = RES_WHITE;
488 break;
489 }
490 return band_color_selection;
491}
492
493enum color do_third_band_menu(void)
494{
495 int band_selection = 0;
496 enum color band_color_selection = 0;
497
498 MENUITEM_STRINGLIST(colors_menu_third, "Third band colour:", NULL,
499 "Black", "Brown", "Red", "Orange", "Yellow",
500 "Green", "Blue", "Silver", "Gold");
501 band_selection = rb->do_menu(&colors_menu_third, &band_selection, NULL,
502 false);
503 switch(band_selection) {
504 case 0: /* Black */
505 band_color_selection = RES_BLACK;
506 break;
507 case 1: /* Brown */
508 band_color_selection = RES_BROWN;
509 break;
510 case 2: /* Red */
511 band_color_selection = RES_RED;
512 break;
513 case 3: /* Orange */
514 band_color_selection = RES_ORANGE;
515 break;
516 case 4: /* Yellow */
517 band_color_selection= RES_YELLOW;
518 break;
519 case 5: /* Green */
520 band_color_selection = RES_GREEN;
521 break;
522 case 6: /* Blue */
523 band_color_selection = RES_BLUE;
524 break;
525 case 7: /* Silver */
526 band_color_selection = RES_SILVER;
527 break;
528 case 8: /* Gold */
529 band_color_selection= RES_GOLD;
530 break;
531 }
532 return band_color_selection;
533}
534
535enum color do_fourth_band_menu(void)
536{
537 int band_selection = 0;
538 enum color band_color_selection = 0;
539
540 MENUITEM_STRINGLIST(colors_menu_fourth, "Fourth band colour:", NULL,
541 "Gold", "Brown", "Red", "Silver", "(none)");
542 band_selection = rb->do_menu(&colors_menu_fourth, &band_selection, NULL,
543 false);
544 switch(band_selection) {
545 case 0: /* Gold */
546 band_color_selection = RES_GOLD;
547 break;
548 case 1: /* Brown */
549 band_color_selection = RES_BROWN;
550 break;
551 case 2: /* Red */
552 band_color_selection = RES_RED;
553 break;
554 case 3: /* Silver */
555 band_color_selection = RES_SILVER;
556 break;
557 case 4: /* (none) */
558 band_color_selection = RES_NONE;
559 break;
560 }
561 return band_color_selection;
562}
563
564void display_helpfile(void)
565{
566 rb->splash(HZ/2, "Helpfile");
567 rb->lcd_clear_display();
568 /* some information obtained from wikipedia */
569 static char * helpfile_text[] = {
570 "Resistor Calculator Helpfile", "", "",
571 "About resistors:", "", /* 7 */
572 /* -- */
573 "A", "resistor", "is", "a ", "two-terminal", "electronic",
574 "component", "that", "produces", "a", "voltage", "across", "its",
575 "terminals", "that", "is", "proportional", "to", "the", "electric",
576 "current", "passing", "through", "it", "in", "accordance", "to",
577 "Ohm's", "Law:", "", /* 29 */
578 /* -- */
579 "", "V = IR",
580 "", "I = V/R",
581 "", "and",
582 "", "R = I/V", "", "",
583 "Where", "V", "=", "voltage", "I", "=", "current", "(in", "amps)",
584 "and", "R", "=", "resistance", "(measured", "in", "Ohms)", "", "",
585 /* 28 */
586 /* -- */
587 "The", "primary", "characteristics", "of", "a", "resistor", "are",
588 "the", "resistance,", "the", "tolerance,", "and", "the", "maximum",
589 "working", "voltage", "and", "the", "power", "rating.", "At",
590 "this", "time,", "this", "calculator", "only", "utilises", "the",
591 "resistance", "and", "tolerance.", "", "", /* 33 */
592 /* -- */
593 "The", "Ohm", "is", "the", "SI", "unit", "of", "resistance,", "and",
594 "common", "multiples", "of", "that", "include", "the", "kiloohm",
595 "(KOhm", "-", "1x10^3)", "and", "the", "megaohm", "(MOhm",
596 "-", "1x10^6),", "both", "of", "which", "are", "supported", "by",
597 "this", "calculator.", "", "", /* 34 */
598 /* -- */
599 "Resistors", "in", "parallel:", "", /* 4 */
600 /* -- */
601 "1/Rtotal", "=", "1/R1", "+", "1/R2", "...", "+", "1/Rn", "", /* 9*/
602 /* -- */
603 "", "Resistors", "in", "series:", "", /* 5 */
604 /* -- */
605 "Rtotal", "=", "R1", "+", "R2", "...", "+", "Rn", "", /* 9 */
606 /* -- */
607 "", "How to use this calculator", "", /* 3 */
608 /* -- */
609 "This", "calculator", "has", "three", "modes:", "",
610 "Resistance", "to", "coulor", "codes,", "",
611 "Colour", "codes", "to", "resistance", "",
612 "and", "LED", "resistance", "calculator", "", "",
613 /* -- */
614 "At", "this", "time", "there", "is", "only", "support", "for",
615 "four-", "band", "resistors.", "", "",
616 /* -- */
617 "In", "Colour", "to", "Resistance", "mode", "use", "the", "menus",
618 "to", "input", "(in", "order)", "the", "bands", "of", "the",
619 "resistor", "for", "which", "you", "would", "like", "to", "know",
620 "the", "resistance.", "", "",
621 /* -- */
622 "In", "Resistance", "to", "Colour", "mode,", "use", "the", "menus",
623 "to", "select", "which", "unit", "to", "use", "(choose", "from", "Ohms,",
624 "KiloOhms", "and", "MegaOhms)", "and", "the", "on-screen", "keyboard",
625 "to", "input", "the", "value", "of", "the", "resistor", "that", "you",
626 "would", "like", "to", "know", "the", "colour", "codes", "of.",
627 "Output", "will", "be", "both", "graphical", "(with", "bands", "of",
628 "the", "resistor", "shown", "in", "their", "corresponding", "colours",
629 "-", "colour", "targets", "only)", "and", "textually.", "","",
630 /* -- */
631 "LED", "resistor", "calculator", "mode", "is", "used", "to", "determine",
632 "the", "resistor", "necessary", "to", "light", "a", "LED", "safely",
633 "at", "a", "given", "voltage.", "First,", "select", "the", "voltage",
634 "that", "the", "LED", "will", "use", "(the", "first", "option", "is",
635 "the", "most", "common", "and", "is", "a", "safe", "guess)", "and", "the",
636 "current", "that", "it", "will", "draw", "(likewise", "with", "the",
637 "first", "option).", "Then", "use", "the", "onscreen", "keyboard", "to",
638 "type", "in", "the", "supply", "voltage", "and,", "if", "selected,",
639 "the", "custom", "foreward", "current.", "",
640 "Disclaimer:", "this",
641 "calculator", "produces", "safe", "estimates,", "but", "use", "your",
642 "own", "judgement", "when", "using", "these", "output", "values.",
643 "Power", "rating", "and", "displayed", "resistance", "are", "rounded",
644 "up", "to", "the", "nearest", "common", "value."
645 };
646 static struct style_text formatting[] = {
647 { 0, TEXT_CENTER|TEXT_UNDERLINE },
648 { 3, TEXT_UNDERLINE },
649 { 159, TEXT_UNDERLINE },
650 LAST_STYLE_ITEM
651 };
652
653 display_text(ARRAYLEN(helpfile_text), helpfile_text, formatting,
654 NULL, true);
655 return;
656}
657
658void led_resistance_calc(void)
659{
660 backlight_force_on();
661 int voltage_menu_selection, button_press, i, j, k, l, foreward_current = 0;
662 int fwd_current_selection = 0;
663 bool quit = false;
664 char kbd_buffer [5];
665 char fwd_kbd_buffer [5];
666 int input_voltage, led_voltage = 0;
667
668 int resistance = 0;
669 int rounded_resistance = 0;
670 int power_rating_in = 0;
671 int rounded_power_rating = 0;
672 int out_int = 0;
673 char current_out_str [16];
674 char true_current_out_str [40];
675 char rounded_resistance_out_str [40];
676 char power_rating_out_str [40];
677
678 int power_ten, first_band_int, second_band_int = 0;
679
680 enum color first_band;
681 enum color second_band;
682 enum color multiplier;
683 enum color fourth_band = RES_NONE;
684
685 rb->splash(HZ/2, "LED resistor calculator");
686 rb->lcd_clear_display();
687
688 MENUITEM_STRINGLIST(voltage_menu, "Select LED voltage:", NULL,
689 "2v (Common red, orange)", "1.5v (IR)", "2.1v (Yellow)",
690 "2.2v (Green)", "3.3v (True green, blue, white, UV)",
691 "4.6v (Blue - 430nm)");
692 MENUITEM_STRINGLIST(fwd_current_menu, "Select foreward current:", NULL,
693 "20mA - Most common for 5mm and 3mm LEDs - select if unsure.",
694 "Key in other (only if already known)");
695
696 while(!quit) {
697 voltage_menu_selection = rb->do_menu(&voltage_menu,
698 &voltage_menu_selection, NULL, false);
699 fwd_current_selection = rb->do_menu(&fwd_current_menu,
700 &fwd_current_selection, NULL, false);
701 rb->lcd_clear_display();
702 rb->splash(HZ*2, "(First) Input the supply voltage:");
703 for(i = 0; i < 5; i++) {kbd_buffer[i] = 0; fwd_kbd_buffer[i] = 0;}
704 rb->kbd_input(kbd_buffer, sizeof(kbd_buffer));
705 input_voltage = rb->atoi(kbd_buffer);
706 if(input_voltage != (int)input_voltage) {
707 input_voltage *= 10;
708 }
709 else { input_voltage *= 100; }
710
711 switch(voltage_menu_selection) {
712 case 0: /* 2v */
713 led_voltage = 200;
714 break;
715 case 1: /* 1.5v */
716 led_voltage = 150;
717 break;
718 case 2: /* 2.1 */
719 led_voltage = 210;
720 break;
721 case 3:
722 led_voltage = 220;
723 break;
724 case 4:
725 led_voltage = 330;
726 break;
727 case 5:
728 led_voltage = 460;
729 break;
730 }
731 switch(fwd_current_selection) {
732 case 0: /* 20mA */
733 foreward_current = 2; /* 20mA * 100 */
734 break;
735 case 1:
736 rb->lcd_clear_display();
737 rb->splash(HZ*2, "Input the foreward current, in mA");
738 rb->kbd_input(fwd_kbd_buffer, sizeof(fwd_kbd_buffer));
739
740 foreward_current = ((rb->atoi(fwd_kbd_buffer))/10);
741 break;
742 }
743
744 rb->lcd_clear_display();
745
746 resistance = (input_voltage - led_voltage) / foreward_current;
747 out_int = resistance;
748
749 int total_common_values = 11;
750 int total_power_values = 9;
751
752 if(led_voltage > input_voltage) {
753 rb->splash(HZ, "Problem: LED voltage is higher than the source.");
754 }
755 else {
756
757 for(j = 0; j < total_common_values; j++) {
758 for(k = 1; k < 5; k++) {
759 if( resistance == (common_values[j] * powi(10, k))) {
760 rounded_resistance = (common_values[j] * powi(10, k));
761 /* perfect match */
762 break;
763 }
764 else if(resistance >= (common_values[j] * powi(10, k)) &&
765 resistance <= (common_values[j+1] * powi(10, k))) {
766 rounded_resistance = (common_values[j+1] * powi(10, k));
767 /* the higher resistance, to be safe */
768 break;
769 }
770 else { break; }
771 }
772 }
773
774 power_rating_in = ((input_voltage/100)*(input_voltage/100)*1000 / rounded_resistance);
775 /* in mW */
776 for(l = 0; l < total_power_values; l++) {
777 if((int)power_rating_in == power_ratings[l]) {
778 rounded_power_rating = (power_ratings[l]);
779 break;
780 }
781 else if(power_rating_in >= power_ratings[l] &&
782 power_rating_in <= power_ratings[l+1]) {
783 rounded_power_rating = power_ratings[l+1];
784 break;
785 }
786 else { break; }
787 }
788
789 get_power_rating_str(rounded_power_rating);
790
791 power_ten = get_power_ten(rounded_resistance);
792 if(rounded_resistance / powi(10, power_ten) == 1) {
793 while(rounded_resistance /powi(10, power_ten) == 1) {
794 power_ten--;
795 }
796 }
797
798 if(rounded_resistance/powi(10, power_ten) != (int)rounded_resistance) {
799 power_ten--; }
800 rounded_resistance /= powi(10, power_ten);
801
802 if(rounded_resistance < 10) {
803 first_band_int = rounded_resistance; }
804 else { first_band_int = rounded_resistance /10; }
805 second_band_int += rounded_resistance % 10;
806
807 if(first_band_int == 10) {
808 first_band_int /= 10;
809 second_band_int = 0;
810 power_ten++;
811 }
812
813 if(first_band_int > 10) {
814 int temp;
815 temp = first_band_int /10;
816 second_band_int = first_band_int % 10;
817 first_band_int = temp;
818 }
819 rounded_resistance *= 10;
820
821 if(rounded_resistance >= 1000) {
822 rounded_resistance /= 10; }
823 /*kludge, maybe. But it fixes the problem (100 ohms graphically,
824 1000 ohms in text displayed */
825
826 first_band = get_band_rtoc(first_band_int);
827 second_band = get_band_rtoc(second_band_int);
828 multiplier = get_band_rtoc(power_ten);
829
830 rb->lcd_clear_display();
831 draw_resistor(first_band, second_band, multiplier, fourth_band);
832 #ifdef HAVE_LCD_COLOR
833 draw_resistor_text(first_band, second_band, multiplier, fourth_band);
834 #endif
835
836 if(fwd_current_selection == 0) {
837 rb->snprintf(current_out_str, sizeof(current_out_str), "20mA");
838 }
839 else if(fwd_current_selection == 1) {
840 rb->snprintf(current_out_str, sizeof(current_out_str), "%d mA",
841 (foreward_current*10));
842 }
843
844 #if (LCD_HEIGHT >= 128)
845 rb->snprintf(true_current_out_str, sizeof(true_current_out_str),
846 "Input: %dv, %d Ohms @ %s", (input_voltage/100),
847 out_int, current_out_str);
848 rb->snprintf(rounded_resistance_out_str,
849 sizeof(rounded_resistance_out_str),
850 "Rounded/displayed: [%d %s]", rounded_resistance,
851 band_data[multiplier].unit);
852 rb->snprintf(power_rating_out_str, sizeof(power_rating_out_str),
853 "Reccomended: %s or greater", power_rating_str);
854 #if (LCD_HEIGHT == 128) /* Fixes an issue with the M:Robe 100 */
855 rb->lcd_putsxy(1, resistance_val_y+25, true_current_out_str);
856 rb->lcd_putsxy(1, resistance_val_y+40, rounded_resistance_out_str);
857 rb->lcd_putsxy(1, resistance_val_y+55, power_rating_out_str);
858 #else /* LCD_HEIGHT == 128 */
859 rb->lcd_putsxy(1, resistance_val_y+15, true_current_out_str);
860 rb->lcd_putsxy(1, resistance_val_y+27, rounded_resistance_out_str);
861 rb->lcd_putsxy(1, resistance_val_y+39, power_rating_out_str);
862 #endif /* LCD_HEIGHT == 128 */
863
864 #else /* (LCD_HEIGHT >= 128) */
865 rb->snprintf(true_current_out_str, sizeof(true_current_out_str),
866 "Input:%dv, %d Ohms @ %s", (input_voltage/100),
867 out_int, current_out_str);
868 rb->snprintf(rounded_resistance_out_str,
869 sizeof(rounded_resistance_out_str), "Rounded: [%d %s]",
870 rounded_resistance, band_data[multiplier].unit);
871 rb->snprintf(power_rating_out_str, sizeof(power_rating_out_str),
872 "Reccommended: %s", power_rating_str);
873
874 #if (LCD_HEIGHT == 80) /* For c200 */
875 rb->lcd_putsxy(0, resistance_val_y, true_current_out_str);
876 rb->lcd_putsxy(0, resistance_val_y+10, rounded_resistance_out_str);
877 rb->lcd_putsxy(0, resistance_val_y+20, power_rating_out_str);
878 #else
879 rb->lcd_puts(resistance_val_x, resistance_val_y+2,
880 true_current_out_str);
881 rb->lcd_puts(resistance_val_x, resistance_val_y+3,
882 rounded_resistance_out_str);
883 rb->lcd_puts(resistance_val_x, resistance_val_y+4,
884 power_rating_out_str);
885 #endif /* LCD_HEIGHT == 80 */
886
887 #endif /* (LCD_HEIGHT >= 128) */
888 /* I have created these separate routines for the different LCDs
889 instead of using lcd_puts_scroll() because it is too buggy
890 to use more than once apparently - the scrolling text is not
891 removed by lcd_clear_display() and can still be seen in the
892 main menu.*/
893 rb->lcd_update();
894 }
895
896 button_press = rb->button_get(true);
897 switch(button_press) {
898 case PLA_SELECT:
899 break;
900 default:
901 quit = true;
902 backlight_use_settings();
903 break;
904 }
905 }
906}
907
908
909void resistance_to_color(void)
910{
911 backlight_force_on();
912 int menu_selection;
913 int menu_selection_tol;
914 int button_press;
915 int i;
916 bool quit = false;
917 char kbd_buffer [10];
918 int kbd_input_int;
919 int in_resistance_int;
920
921 int power_ten;
922 int first_band_int = 0;
923 int second_band_int = 0;
924
925 enum color first_band;
926 enum color second_band;
927 enum color multiplier;
928 enum color fourth_band = 0;
929 enum color units_used = 0;
930
931 char out_str[20];
932
933 for(i=0; i<=10; i++) { kbd_buffer[i] = 0; }
934 /* This cleans out the mysterious garbage that appears */
935 rb->lcd_clear_display();
936 rb->splash(HZ/2, "Resistance to Colour");
937 MENUITEM_STRINGLIST(r_to_c_menu, "Select unit to use:", NULL,
938 "Ohms", "Kiloohms (KOhms)", "Megaohms (MOhms)");
939 MENUITEM_STRINGLIST(r_to_c_menu_tol, "Tolerance to display:", NULL,
940 "5%", "10%", "1%", "2%", "20%");
941
942 while(!quit) {
943 menu_selection = rb->do_menu(&r_to_c_menu, &menu_selection,
944 NULL, false);
945
946 rb->kbd_input(kbd_buffer, sizeof(kbd_buffer));
947 /* As stated above somewhere, we (I) need to make a calculator-like
948 keypad, that keyboard isn't all that fun to use. */
949 menu_selection_tol = rb->do_menu(&r_to_c_menu_tol, &menu_selection_tol,
950 NULL, false);
951 switch(menu_selection_tol) {
952 case 0: /* 5% */
953 fourth_band = RES_GOLD;
954 break;
955 case 1: /* 10% */
956 fourth_band = RES_SILVER;
957 break;
958 case 2: /* 1% */
959 fourth_band = RES_BROWN;
960 break;
961 case 3: /* 2% */
962 fourth_band = RES_RED;
963 break;
964 case 4: /* 20% */
965 fourth_band = RES_NONE;
966 break;
967 }
968
969 kbd_input_int = rb->atoi(kbd_buffer);
970 in_resistance_int = kbd_input_int;
971
972 switch(menu_selection) {
973 case 0:
974 units_used = RES_BLACK;
975 break;
976 case 1: /* KOhms */
977 units_used = RES_RED;
978 kbd_input_int *= 1000;
979 break;
980 case 2: /* MOhms */
981 units_used = RES_GREEN;
982 kbd_input_int *= 1000000;
983 break;
984 }
985
986 power_ten = get_power_ten(kbd_input_int);
987 if(kbd_input_int / powi(10, power_ten) == 1) {
988 while(kbd_input_int /powi(10, power_ten) == 1) {
989 power_ten--;
990 }
991 }
992
993 if(kbd_input_int / powi(10, power_ten) != (int)kbd_input_int) {
994 power_ten--; }
995 kbd_input_int /= powi(10, power_ten);
996
997 if(kbd_input_int < 10) {
998 first_band_int = kbd_input_int; }
999 else { first_band_int = kbd_input_int /10; }
1000 second_band_int += kbd_input_int % 10;
1001
1002 if(first_band_int == 10) {
1003 first_band_int /= 10;
1004 second_band_int = 0;
1005 power_ten++;
1006 }
1007
1008 if(first_band_int > 10) {
1009 int temp;
1010 temp = first_band_int /10;
1011 second_band_int = first_band_int % 10;
1012 first_band_int = temp;
1013 }
1014
1015 first_band = get_band_rtoc(first_band_int);
1016 second_band = get_band_rtoc(second_band_int);
1017 multiplier = get_band_rtoc(power_ten);
1018
1019 rb->lcd_clear_display();
1020 draw_resistor(first_band, second_band, multiplier, fourth_band);
1021
1022 #ifdef HAVE_LCD_COLOR /* This seems backwards, but is really only
1023 necessary on color targets */
1024 draw_resistor_text(first_band, second_band,
1025 multiplier, fourth_band);
1026 #endif
1027
1028 rb->snprintf(out_str, sizeof(out_str), "Input: %d %s", in_resistance_int,
1029 band_data[units_used].unit);
1030 rb->lcd_putsxy(r_to_c_out_str_x, r_to_c_out_str_y, out_str);
1031 rb->lcd_update();
1032
1033 button_press = rb->button_get(true);
1034 switch(button_press) {
1035 case PLA_SELECT:
1036 break;
1037 default:
1038 quit = true;
1039 backlight_use_settings();
1040 break;
1041 }
1042 }
1043}
1044
1045void color_to_resistance(void)
1046{
1047 backlight_force_on();
1048 bool quit = false;
1049 int button_input = 0;
1050
1051 /* The colors of the bands */
1052 enum color first_band = 0;
1053 enum color second_band = 0;
1054 enum color third_band = 0;
1055 enum color fourth_band = 0;
1056
1057 int total_resistance_centiunits = 0;
1058 char total_resistance_str [35];
1059
1060 rb->splash(HZ/2, "Colour to resistance");
1061 rb->lcd_clear_display();
1062
1063 while(!quit) {
1064 first_band = do_first_band_menu();
1065 second_band = do_second_band_menu();
1066 third_band = do_third_band_menu();
1067 fourth_band = do_fourth_band_menu();
1068
1069 total_resistance_centiunits = calculate_resistance(first_band,
1070 second_band,
1071 third_band);
1072 get_tolerance_str(fourth_band);
1073 draw_resistor(first_band, second_band, third_band, fourth_band);
1074 #ifndef USE_TEXT_ONLY
1075 rb->lcd_set_foreground(LCD_WHITE);
1076 #endif
1077 if(total_resistance_centiunits % 100 == 0)
1078 {
1079 /* No decimals */
1080 rb->snprintf(total_resistance_str, sizeof(total_resistance_str),
1081 "Resistance: %d %s",
1082 total_resistance_centiunits/100,
1083 unit_abbrev);
1084 }
1085 else
1086 {
1087 rb->snprintf(total_resistance_str, sizeof(total_resistance_str),
1088 "Resistance: %d.%d %s",
1089 total_resistance_centiunits/100,
1090 total_resistance_centiunits%100,
1091 unit_abbrev);
1092 }
1093 rb->lcd_putsxy(total_resistance_str_x, total_resistance_str_y,
1094 total_resistance_str);
1095 rb->lcd_putsxy(tolerance_str_x, tolerance_str_y, tolerance_str);
1096 rb->lcd_update();
1097
1098 button_input = rb->button_get(true);
1099 switch(button_input) {
1100 case PLA_RIGHT:
1101 break;
1102 case PLA_EXIT:
1103 case PLA_SELECT:
1104 default:
1105 quit = true;
1106 backlight_use_settings();
1107 break;
1108 }
1109 }
1110 return;
1111}
1112
1113enum plugin_status plugin_start(const void* nothing)
1114{
1115 (void)nothing;
1116 rb->lcd_clear_display();
1117 rb->lcd_update();
1118 int main_menu_selection = 0;
1119 bool menuquit = false;
1120 int event;
1121
1122 MENUITEM_STRINGLIST(main_menu, "Resistor Code Calculator:", NULL,
1123 "Colours -> Resistance", "Resistance -> Colours",
1124 "LED resistor calculator", "Help", "Exit");
1125 while (!menuquit) {
1126 main_menu_selection = rb->do_menu(&main_menu, &main_menu_selection,
1127 NULL, false);
1128 switch(main_menu_selection) {
1129 case 0:
1130 color_to_resistance();
1131 break;
1132 case 1:
1133 resistance_to_color();
1134 break;
1135 case 2:
1136 led_resistance_calc();
1137 break;
1138 case 3:
1139 display_helpfile();
1140 break;
1141 case 4:
1142 menuquit = true;
1143 break;
1144 }
1145 event = rb->button_get(true);
1146 if(rb->default_event_handler(event) == SYS_USB_CONNECTED) {
1147 return PLUGIN_USB_CONNECTED; }
1148 }
1149 return PLUGIN_OK;
1150}