Initial 800x480 cabbiev2 port, based on 480x800x16 one
[kugel-rb.git] / apps / plugins / resistor.c
blobeb02ce6d8dd77e0285644d9eb4f63d315a90c17d
1 /* === Rockbox Resistor code/value calculator ===
2 [insert relevant/useful information here]
3 TODO:
4 [ ] Own numeric keypad
5 */
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"
13 /* Defining player-specific constants */
15 #if defined(HAVE_LCD_COLOR)
16 #define RESISTOR_BMP_X ((LCD_WIDTH - BMPWIDTH_resistor) / 2)
18 #if LCD_WIDTH >= 320 && LCD_HEIGHT >= 240 /* iPod video or larger */
19 #define RESISTOR_BMP_Y 3
21 #elif LCD_WIDTH >= 240 && LCD_HEIGHT >= 320 /* Onda, mostly */
22 #define RESISTOR_BMP_Y 3
24 #elif LCD_WIDTH >= 220 && LCD_HEIGHT >= 176 /* Fuze or larger */
25 #define RESISTOR_BMP_Y 15
27 #elif LCD_WIDTH >= 176 && LCD_HEIGHT >= 220 /* e200 or larger */
28 #define RESISTOR_BMP_Y 11
30 #elif LCD_WIDTH >= 176 && LCD_HEIGHT >= 132 /* ipod nano or larger */
31 #define RESISTOR_BMP_Y 7
33 #elif LCD_WIDTH >= 160 && LCD_HEIGHT >= 128 /* H10 or larger */
34 #define RESISTOR_BMP_Y 3
36 #elif LCD_WIDTH >= 128 && LCD_HEIGHT >= 128 /* GoGear */
37 #define RESISTOR_BMP_Y 3
39 #else /* Small screens */
40 #define RESISTOR_BMP_Y 0
42 #endif
44 #else /* HAVE_LCD_COLOR */
46 #define USE_TEXT_ONLY
47 #endif /* HAVE_LCD_COLOR */
49 #define total_resistance_str_x 1
50 #define tolerance_str_x 1
51 #define resistance_val_x 1
52 #define r_to_c_out_str_x 1
54 #define INITIAL_TEXT_Y 0
56 #ifndef USE_TEXT_ONLY
57 /* (below is for color targets */
59 #include "pluginbitmaps/resistor.h"
61 #define band_width (BMPWIDTH_resistor/15)
62 #define band_height (BMPHEIGHT_resistor*9/10)
64 #define first_band_x (BMPWIDTH_resistor/4 + RESISTOR_BMP_X - band_width/2)
65 #define second_band_x (3*BMPWIDTH_resistor/8 + RESISTOR_BMP_X - band_width/2)
66 #define third_band_x (BMPWIDTH_resistor/2 + RESISTOR_BMP_X - band_width/2)
67 #define fourth_band_x (3*BMPWIDTH_resistor/4 + RESISTOR_BMP_X - band_width/2)
68 #define universal_y ((BMPHEIGHT_resistor)/2 - band_height/2)
70 #endif /* USE_TEXT_ONLY */
72 enum color {
73 RES_BLACK,
74 RES_BROWN,
75 RES_RED,
76 RES_ORANGE,
77 RES_YELLOW,
78 RES_GREEN,
79 RES_BLUE,
80 RES_VIOLET,
81 RES_GREY,
82 RES_WHITE,
83 RES_GOLD,
84 RES_SILVER,
85 RES_NONE,
86 RES_INVALID = -1,
89 static int common_values[] = { 0, 1, 10, 15, 22, 27, 33, 39, 47, 51, 68, 82 };
90 static int power_ratings[] = { 125, 250, 500, 1000, 2000, 3000, 5000, 10000, 50000 };
91 /* All in mW */
93 #ifndef LCD_RGBPACK
94 /* Warning: dirty kludge */
95 #define LCD_RGBPACK(x,y,z) 0
96 #endif
98 static struct band_data
100 enum color color;
101 char *name;
102 int color_value;
103 int resistance_value;
104 int multiplier;
105 char *unit;
106 int tolerance;
107 } band_data[] =
109 { RES_BLACK, "Black", LCD_RGBPACK(0, 0, 0), 0, 100, "Ohms",-1 },
110 { RES_BROWN, "Brown", LCD_RGBPACK(118, 78, 0), 1, 1000, "Ohms", 1 },
111 { RES_RED, "Red", LCD_RGBPACK(255, 0, 0), 2, 10000, "Ohms", 2 },
112 { RES_ORANGE, "Orange", LCD_RGBPACK(255, 199, 76), 3, 100, "KOhms",-1 },
113 { RES_YELLOW, "Yellow", LCD_RGBPACK(255, 255, 0), 4, 1000, "KOhms",-1 },
114 { RES_GREEN, "Green", LCD_RGBPACK(0, 128, 0), 5, 10000, "KOhms",-1 },
115 { RES_BLUE, "Blue", LCD_RGBPACK(0, 0, 255), 6, 100, "MOhms",-1 },
116 { RES_VIOLET, "Violet", LCD_RGBPACK(153, 51, 255), 7, 1000, "MOhms",-1 },
117 { RES_GREY, "Grey", LCD_RGBPACK(192, 192, 192), 8, 10000, "MOhms",-1 },
118 { RES_WHITE, "White", LCD_RGBPACK(255, 255, 255), 9, 100, "GOhms",-1 },
119 { RES_GOLD, "Gold", LCD_RGBPACK(146, 146, 0), -1, 10, "Ohms", 5 },
120 { RES_SILVER, "Silver", LCD_RGBPACK(213, 213, 213),-1, 1, "Ohms", 10 },
121 { RES_NONE, "[None]", -1 ,-1, -1, 0, 20 }
124 static char *unit_abbrev;
126 static struct viewport screen_vp;
127 static struct viewport bitmap_vp;
128 static struct viewport text_vp;
129 static struct screen *display;
131 static int lineno;
133 static char *get_power_rating_str(int in_rating)
135 switch(in_rating) {
136 case 125:
137 return "1/8 Watt";
138 case 250:
139 return "1/4 Watt";
140 case 500:
141 return "1/2 Watt";
142 case 1000:
143 return "1 Watt";
144 case 2000:
145 return "2 Watt";
146 case 3000:
147 return "3 Watt";
148 case 5000:
149 return "5 Watt";
150 case 10000:
151 return "10 Watt";
152 case 500000:
153 return "50 Watt";
154 default:
155 return "Unknown";
159 static int powi(int num, int exp)
161 int i, product = 1;
162 for (i = 0; i < exp; i++) {
163 product *= num; }
165 return product;
168 static enum color get_band_rtoc(int in_val)
170 int return_color = RES_INVALID;
171 switch(in_val) {
172 case 0:
173 return_color = RES_BLACK;
174 break;
175 case 1:
176 return_color = RES_BROWN;
177 break;
178 case 2:
179 return_color = RES_RED;
180 break;
181 case 3:
182 return_color = RES_ORANGE;
183 break;
184 case 4:
185 return_color = RES_YELLOW;
186 break;
187 case 5:
188 return_color = RES_GREEN;
189 break;
190 case 6:
191 return_color = RES_BLUE;
192 break;
193 case 7:
194 return_color = RES_VIOLET;
195 break;
196 case 8:
197 return_color = RES_GREY;
198 break;
199 case 9:
200 return_color = RES_WHITE;
201 break;
203 return return_color;
206 static char *get_tolerance_str(enum color color)
208 static char tolerance_str [14];
209 rb->snprintf(tolerance_str, sizeof(tolerance_str), "%d%% tolerance",
210 band_data[color].tolerance);
211 return tolerance_str;
214 #ifndef USE_TEXT_ONLY
215 static void draw_resistor(enum color firstband_color,
216 enum color secondband_color,
217 enum color thirdband_color,
218 enum color fourthband_color)
220 unsigned int fg;
222 rb->lcd_clear_display();
223 display->set_viewport(&bitmap_vp);
224 rb->lcd_bitmap_transparent(resistor, RESISTOR_BMP_X, 0,
225 BMPWIDTH_resistor, BMPHEIGHT_resistor);
227 fg = rb->lcd_get_foreground();
229 if(firstband_color != RES_NONE) {
230 rb->lcd_set_foreground(band_data[firstband_color].color_value);
231 rb->lcd_fillrect(first_band_x, universal_y, band_width, band_height);
232 } else {
233 rb->lcd_set_foreground(LCD_BLACK);
234 rb->lcd_drawrect(first_band_x, universal_y, band_width, band_height);
237 if(secondband_color != RES_NONE) {
238 rb->lcd_set_foreground(band_data[secondband_color].color_value);
239 rb->lcd_fillrect(second_band_x, universal_y, band_width, band_height);
240 } else {
241 rb->lcd_set_foreground(LCD_BLACK);
242 rb->lcd_drawrect(second_band_x, universal_y, band_width, band_height);
245 if(thirdband_color != RES_NONE) {
246 rb->lcd_set_foreground(band_data[thirdband_color].color_value);
247 rb->lcd_fillrect(third_band_x, universal_y, band_width, band_height);
248 } else {
249 rb->lcd_set_foreground(LCD_BLACK);
250 rb->lcd_drawrect(third_band_x, universal_y, band_width, band_height);
253 if(fourthband_color != RES_NONE) {
254 rb->lcd_set_foreground(band_data[fourthband_color].color_value);
255 rb->lcd_fillrect(fourth_band_x, universal_y, band_width, band_height);
256 } else {
257 rb->lcd_set_foreground(LCD_BLACK);
258 rb->lcd_drawrect(fourth_band_x, universal_y, band_width, band_height);
261 rb->lcd_set_foreground(fg);
263 rb->lcd_update();
264 return;
266 #endif
268 static void draw_resistor_text(enum color firstband_color,
269 enum color secondband_color,
270 enum color thirdband_color,
271 enum color fourthband_color)
273 char resistance_vals_str[64];
274 display->set_viewport(&text_vp);
275 rb->snprintf(resistance_vals_str, sizeof(resistance_vals_str),
276 "%s - %s - %s - %s", band_data[firstband_color].name,
277 band_data[secondband_color].name,
278 band_data[thirdband_color].name,
279 band_data[fourthband_color].name);
280 rb->lcd_puts_scroll(resistance_val_x, lineno++, resistance_vals_str);
281 rb->lcd_update();
285 static int calculate_resistance(enum color first_band,
286 enum color second_band,
287 enum color third_band)
289 int tens = band_data[first_band].resistance_value;
290 int units = band_data[second_band].resistance_value;
291 int multiplier = band_data[third_band].multiplier;
292 int total_resistance_centiunits = (10 * tens + units ) * multiplier;
294 unit_abbrev = band_data[third_band].unit;
296 return total_resistance_centiunits;
299 static enum color do_first_band_menu(void)
301 int band_selection = 0;
302 enum color band_color_selection = 0;
304 MENUITEM_STRINGLIST(colors_menu_first, "First band colour:", NULL,
305 "Black", "Brown", "Red", "Orange", "Yellow",
306 "Green", "Blue", "Violet", "Grey", "White");
307 band_selection = rb->do_menu(&colors_menu_first, &band_selection, NULL,
308 false);
309 switch(band_selection) {
310 case 0: /* Black */
311 band_color_selection = RES_BLACK;
312 break;
313 case 1: /* Brown */
314 band_color_selection = RES_BROWN;
315 break;
316 case 2: /* Red */
317 band_color_selection = RES_RED;
318 break;
319 case 3: /* Orange */
320 band_color_selection = RES_ORANGE;
321 break;
322 case 4: /* Yellow */
323 band_color_selection = RES_YELLOW;
324 break;
325 case 5: /* Green */
326 band_color_selection = RES_GREEN;
327 break;
328 case 6: /* Blue */
329 band_color_selection = RES_BLUE;
330 break;
331 case 7: /* Violet */
332 band_color_selection = RES_VIOLET;
333 break;
334 case 8: /* Grey */
335 band_color_selection = RES_GREY;
336 break;
337 case 9: /* White */
338 band_color_selection = RES_WHITE;
339 break;
340 default:
341 band_color_selection = RES_INVALID;
342 break;
344 return band_color_selection;
347 static enum color do_second_band_menu(void)
349 int band_selection = 0;
350 enum color band_color_selection = 0;
352 MENUITEM_STRINGLIST(colors_menu_second, "Second band colour:", NULL,
353 "Black", "Brown", "Red", "Orange", "Yellow",
354 "Green", "Blue", "Violet", "Grey", "White");
355 band_selection = rb->do_menu(&colors_menu_second, &band_selection, NULL,
356 false);
357 switch(band_selection) {
358 case 0: /* Black */
359 band_color_selection = RES_BLACK;
360 break;
361 case 1: /* Brown */
362 band_color_selection = RES_BROWN;
363 break;
364 case 2: /* Red */
365 band_color_selection = RES_RED;
366 break;
367 case 3: /* Orange */
368 band_color_selection = RES_ORANGE;
369 break;
370 case 4: /* Yellow */
371 band_color_selection = RES_YELLOW;
372 break;
373 case 5: /* Green */
374 band_color_selection = RES_GREEN;
375 break;
376 case 6: /* Blue */
377 band_color_selection = RES_BLUE;
378 break;
379 case 7: /* Violet */
380 band_color_selection = RES_VIOLET;
381 break;
382 case 8: /* Grey */
383 band_color_selection = RES_GREY;
384 break;
385 case 9: /* White */
386 band_color_selection = RES_WHITE;
387 break;
388 default:
389 band_color_selection = RES_INVALID;
390 break;
392 return band_color_selection;
395 static enum color do_third_band_menu(void)
397 int band_selection = 0;
398 enum color band_color_selection = 0;
400 MENUITEM_STRINGLIST(colors_menu_third, "Third band colour:", NULL,
401 "Black", "Brown", "Red", "Orange", "Yellow",
402 "Green", "Blue", "Violet", "Grey", "White",
403 "Silver", "Gold");
404 band_selection = rb->do_menu(&colors_menu_third, &band_selection, NULL,
405 false);
406 switch(band_selection) {
407 case 0: /* Black */
408 band_color_selection = RES_BLACK;
409 break;
410 case 1: /* Brown */
411 band_color_selection = RES_BROWN;
412 break;
413 case 2: /* Red */
414 band_color_selection = RES_RED;
415 break;
416 case 3: /* Orange */
417 band_color_selection = RES_ORANGE;
418 break;
419 case 4: /* Yellow */
420 band_color_selection= RES_YELLOW;
421 break;
422 case 5: /* Green */
423 band_color_selection = RES_GREEN;
424 break;
425 case 6: /* Blue */
426 band_color_selection = RES_BLUE;
427 break;
428 case 7: /* Violet */
429 band_color_selection = RES_VIOLET;
430 break;
431 case 8: /* Grey */
432 band_color_selection = RES_GREY;
433 break;
434 case 9: /* White */
435 band_color_selection = RES_WHITE;
436 break;
437 case 10: /* Silver */
438 band_color_selection = RES_SILVER;
439 break;
440 case 11: /* Gold */
441 band_color_selection= RES_GOLD;
442 break;
443 default:
444 band_color_selection = RES_INVALID;
445 break;
447 return band_color_selection;
450 static enum color do_fourth_band_menu(void)
452 int band_selection = 0;
453 enum color band_color_selection = 0;
455 MENUITEM_STRINGLIST(colors_menu_fourth, "Fourth band colour:", NULL,
456 "Gold", "Brown", "Red", "Silver", "(none)");
457 band_selection = rb->do_menu(&colors_menu_fourth, &band_selection, NULL,
458 false);
459 switch(band_selection) {
460 case 0: /* Gold */
461 band_color_selection = RES_GOLD;
462 break;
463 case 1: /* Brown */
464 band_color_selection = RES_BROWN;
465 break;
466 case 2: /* Red */
467 band_color_selection = RES_RED;
468 break;
469 case 3: /* Silver */
470 band_color_selection = RES_SILVER;
471 break;
472 case 4: /* (none) */
473 band_color_selection = RES_NONE;
474 break;
475 default:
476 band_color_selection = RES_INVALID;
477 break;
479 return band_color_selection;
482 static void display_helpfile(void)
484 rb->lcd_clear_display();
485 /* some information obtained from wikipedia */
486 static char * helpfile_text[] = {
487 "Resistor Calculator Helpfile", "", "",
488 "About resistors:", "", /* 7 */
489 /* -- */
490 "A", "resistor", "is", "a ", "two-terminal", "electronic",
491 "component", "that", "produces", "a", "voltage", "across", "its",
492 "terminals", "that", "is", "proportional", "to", "the", "electric",
493 "current", "passing", "through", "it", "in", "accordance", "to",
494 "Ohm's", "Law:", "", /* 29 */
495 /* -- */
496 "", "V = IR",
497 "", "I = V/R",
498 "", "and",
499 "", "R = I/V", "", "",
500 "Where", "V", "=", "voltage", "I", "=", "current", "(in", "amps)",
501 "and", "R", "=", "resistance", "(measured", "in", "Ohms)", "", "",
502 /* 28 */
503 /* -- */
504 "The", "primary", "characteristics", "of", "a", "resistor", "are",
505 "the", "resistance,", "the", "tolerance,", "and", "the", "maximum",
506 "working", "voltage", "and", "the", "power", "rating.", "At",
507 "this", "time,", "this", "calculator", "only", "utilises", "the",
508 "resistance", "and", "tolerance.", "", "", /* 33 */
509 /* -- */
510 "The", "Ohm", "is", "the", "SI", "unit", "of", "resistance,", "and",
511 "common", "multiples", "of", "that", "include", "the", "kiloohm",
512 "(KOhm", "-", "1x10^3)", "and", "the", "megaohm", "(MOhm",
513 "-", "1x10^6),", "both", "of", "which", "are", "supported", "by",
514 "this", "calculator.", "", "", /* 34 */
515 /* -- */
516 "Resistors", "in", "parallel:", "", /* 4 */
517 /* -- */
518 "1/Rtotal", "=", "1/R1", "+", "1/R2", "...", "+", "1/Rn", "", /* 9*/
519 /* -- */
520 "", "Resistors", "in", "series:", "", /* 5 */
521 /* -- */
522 "Rtotal", "=", "R1", "+", "R2", "...", "+", "Rn", "", /* 9 */
523 /* -- */
524 "", "How to use this calculator", "", /* 3 */
525 /* -- */
526 "This", "calculator", "has", "three", "modes:", "",
527 "Resistance", "to", "colour", "codes,", "",
528 "Colour", "codes", "to", "resistance", "",
529 "and", "LED", "resistance", "calculator", "", "",
530 /* -- */
531 "At", "this", "time", "there", "is", "only", "support", "for",
532 "four-", "band", "resistors.", "", "",
533 /* -- */
534 "In", "Colour", "to", "Resistance", "mode", "use", "the", "menus",
535 "to", "input", "(in", "order)", "the", "bands", "of", "the",
536 "resistor", "for", "which", "you", "would", "like", "to", "know",
537 "the", "resistance.", "", "",
538 /* -- */
539 "In", "Resistance", "to", "Colour", "mode,", "use", "the", "menus",
540 "to", "select", "which", "unit", "to", "use", "(choose", "from", "Ohms,",
541 "KiloOhms", "and", "MegaOhms)", "and", "the", "on-screen", "keyboard",
542 "to", "input", "the", "value", "of", "the", "resistor", "that", "you",
543 "would", "like", "to", "know", "the", "colour", "codes", "of.",
544 "Output", "will", "be", "both", "graphical", "(with", "bands", "of",
545 "the", "resistor", "shown", "in", "their", "corresponding", "colours",
546 "-", "colour", "targets", "only)", "and", "textually.", "","",
547 /* -- */
548 "LED", "resistor", "calculator", "mode", "is", "used", "to", "determine",
549 "the", "resistor", "necessary", "to", "light", "a", "LED", "safely",
550 "at", "a", "given", "voltage.", "First,", "select", "the", "voltage",
551 "that", "the", "LED", "will", "use", "(the", "first", "option", "is",
552 "the", "most", "common", "and", "is", "a", "safe", "guess)", "and", "the",
553 "current", "that", "it", "will", "draw", "(likewise", "with", "the",
554 "first", "option).", "Then", "use", "the", "onscreen", "keyboard", "to",
555 "type", "in", "the", "supply", "voltage", "and,", "if", "selected,",
556 "the", "custom", "foreward", "current.", "",
557 "Disclaimer:", "this",
558 "calculator", "produces", "safe", "estimates,", "but", "use", "your",
559 "own", "judgement", "when", "using", "these", "output", "values.",
560 "Power", "rating", "and", "displayed", "resistance", "are", "rounded",
561 "up", "to", "the", "nearest", "common", "value."
563 static struct style_text formatting[] = {
564 { 0, TEXT_CENTER|TEXT_UNDERLINE },
565 { 3, TEXT_UNDERLINE },
566 { 159, TEXT_UNDERLINE },
567 LAST_STYLE_ITEM
570 display_text(ARRAYLEN(helpfile_text), helpfile_text, formatting,
571 NULL, true);
572 return;
575 static void led_resistance_calc(void)
577 backlight_force_on();
578 int voltage_menu_selection, button_press, j, k, l, foreward_current = 0;
579 int fwd_current_selection = 0;
580 bool quit = false;
581 char kbd_buffer [5];
582 char fwd_kbd_buffer [5];
583 int input_voltage, led_voltage = 0;
585 int resistance = 0;
586 int rounded_resistance = 0;
587 int temp;
588 int power_rating_in = 0;
589 int rounded_power_rating = 0;
590 int out_int = 0;
591 char current_out_str [16];
592 char true_current_out_str [40];
593 char rounded_resistance_out_str [40];
594 char power_rating_out_str [40];
596 int power_ten, first_band_int, second_band_int = 0;
598 enum color first_band;
599 enum color second_band;
600 enum color multiplier;
601 enum color fourth_band = RES_NONE;
603 rb->lcd_clear_display();
605 MENUITEM_STRINGLIST(voltage_menu, "Select LED voltage:", NULL,
606 "2v (Common red, orange)", "1.5v (IR)", "2.1v (Yellow)",
607 "2.2v (Green)", "3.3v (True green, blue, white, UV)",
608 "4.6v (Blue - 430nm)");
609 MENUITEM_STRINGLIST(fwd_current_menu, "Select foreward current:", NULL,
610 "20mA - Most common for 5mm and 3mm LEDs - select if unsure.",
611 "Key in other (only if already known)");
613 while(!quit) {
614 int ret;
615 ret = voltage_menu_selection = rb->do_menu(&voltage_menu,
616 &voltage_menu_selection, NULL, false);
617 if(ret<0) break;
618 ret = fwd_current_selection = rb->do_menu(&fwd_current_menu,
619 &fwd_current_selection, NULL, false);
620 if(ret<0) break;
621 rb->lcd_clear_display();
624 rb->splash(HZ*2, "(First) Input the supply voltage:");
625 memset(kbd_buffer,0,sizeof(kbd_buffer));
626 rb->kbd_input(kbd_buffer, sizeof(kbd_buffer));
627 input_voltage = rb->atoi(kbd_buffer);
628 if(input_voltage == 0) break;
630 if(input_voltage != (int)input_voltage) {
631 input_voltage *= 10;
633 else { input_voltage *= 100; }
635 switch(voltage_menu_selection) {
636 case 0: /* 2v */
637 led_voltage = 200;
638 break;
639 case 1: /* 1.5v */
640 led_voltage = 150;
641 break;
642 case 2: /* 2.1 */
643 led_voltage = 210;
644 break;
645 case 3:
646 led_voltage = 220;
647 break;
648 case 4:
649 led_voltage = 330;
650 break;
651 case 5:
652 led_voltage = 460;
653 break;
655 switch(fwd_current_selection) {
656 case 0: /* 20mA */
657 foreward_current = 2; /* 20mA * 100 */
658 break;
659 case 1:
660 rb->lcd_clear_display();
661 rb->splash(HZ*2, "Input the foreward current, in mA");
662 memset(fwd_kbd_buffer,0,sizeof(fwd_kbd_buffer));
663 rb->kbd_input(fwd_kbd_buffer, sizeof(fwd_kbd_buffer));
664 foreward_current = ((rb->atoi(fwd_kbd_buffer))/10);
665 break;
668 if(foreward_current == 0) break;
670 rb->lcd_clear_display();
672 resistance = (input_voltage - led_voltage) / foreward_current;
673 out_int = resistance;
675 int total_common_values = 11;
676 int total_power_values = 9;
678 if(led_voltage > input_voltage) {
679 rb->splash(HZ, "Problem: LED voltage is higher than the source.");
680 break;
683 for(j = 0; j < total_common_values; j++) {
684 for(k = 1; k < 5; k++) {
685 if( resistance == (common_values[j] * powi(10, k))) {
686 rounded_resistance = (common_values[j] * powi(10, k));
687 /* perfect match */
688 break;
690 else if(resistance >= (common_values[j] * powi(10, k)) &&
691 resistance <= (common_values[j+1] * powi(10, k))) {
692 rounded_resistance = (common_values[j+1] * powi(10, k));
693 /* the higher resistance, to be safe */
694 break;
696 else { break; }
700 if(rounded_resistance == 0)
702 rb->splash(HZ, "Problem: Input voltage too high.");
703 break;
705 power_rating_in = ((input_voltage/100)*(input_voltage/100)*1000 / rounded_resistance);
706 /* in mW */
707 for(l = 0; l < total_power_values; l++) {
708 if((int)power_rating_in == power_ratings[l]) {
709 rounded_power_rating = (power_ratings[l]);
710 break;
712 else if(power_rating_in >= power_ratings[l] &&
713 power_rating_in <= power_ratings[l+1]) {
714 rounded_power_rating = power_ratings[l+1];
715 break;
717 else { break; }
720 get_power_rating_str(rounded_power_rating);
722 power_ten=0;
723 temp=rounded_resistance;
724 while(temp>=100) {
725 temp/=10;
726 power_ten++;
728 first_band_int=temp/10;
729 second_band_int=temp%10;
731 first_band = get_band_rtoc(first_band_int);
732 second_band = get_band_rtoc(second_band_int);
733 multiplier = get_band_rtoc(power_ten);
735 rb->lcd_clear_display();
736 lineno = INITIAL_TEXT_Y;
737 #ifndef USE_TEXT_ONLY
738 draw_resistor(first_band, second_band, multiplier, fourth_band);
739 #endif
740 draw_resistor_text(first_band, second_band, multiplier, fourth_band);
742 rb->snprintf(current_out_str, sizeof(current_out_str), "%d mA",
743 (foreward_current*10));
745 rb->snprintf(true_current_out_str, sizeof(true_current_out_str),
746 "Input: %dv, %d Ohms @ %s", (input_voltage/100),
747 out_int, current_out_str);
748 rb->snprintf(rounded_resistance_out_str,
749 sizeof(rounded_resistance_out_str),
750 "Rounded/displayed: [%d %s]", rounded_resistance,
751 band_data[multiplier].unit);
752 rb->snprintf(power_rating_out_str, sizeof(power_rating_out_str),
753 "Recommended: %s or greater",
754 get_power_rating_str(rounded_power_rating));
756 display->set_viewport(&text_vp);
757 rb->lcd_puts_scroll(resistance_val_x, lineno++, true_current_out_str);
758 rb->lcd_puts_scroll(resistance_val_x, lineno++, rounded_resistance_out_str);
759 rb->lcd_puts_scroll(resistance_val_x, lineno++, power_rating_out_str);
761 rb->lcd_update();
763 button_press = rb->button_get(true);
764 switch(button_press) {
765 case PLA_SELECT:
766 break;
767 default:
768 quit = true;
769 backlight_use_settings();
770 break;
773 display->set_viewport(&text_vp);
774 rb->lcd_stop_scroll();
775 display->set_viewport(&screen_vp);
776 rb->lcd_clear_display();
780 static void resistance_to_color(void)
782 backlight_force_on();
783 int menu_selection;
784 int menu_selection_tol;
785 int button_press;
786 int i;
787 bool quit = false;
788 char kbd_buffer [10];
789 int kbd_input_int;
790 int temp;
791 int in_resistance_int;
793 int power_ten=0;
794 int first_band_int = 0;
795 int second_band_int = 0;
797 enum color first_band;
798 enum color second_band;
799 enum color multiplier;
800 enum color fourth_band = 0;
801 enum color units_used = 0;
803 char out_str[20];
805 for(i=0; i<=10; i++) { kbd_buffer[i] = 0; }
806 /* This cleans out the mysterious garbage that appears */
807 rb->lcd_clear_display();
808 rb->splash(HZ/2, "Resistance to Colour");
809 MENUITEM_STRINGLIST(r_to_c_menu, "Select unit to use:", NULL,
810 "Ohms", "Kiloohms (KOhms)", "Megaohms (MOhms)",
811 "Gigaohms (GOhms)");
812 MENUITEM_STRINGLIST(r_to_c_menu_tol, "Tolerance to display:", NULL,
813 "5%", "10%", "1%", "2%", "20%");
815 while(!quit) {
816 int ret;
817 ret=menu_selection = rb->do_menu(&r_to_c_menu, &menu_selection,
818 NULL, false);
819 if(ret<0) break;
821 rb->kbd_input(kbd_buffer, sizeof(kbd_buffer));
822 /* As stated above somewhere, we (I) need to make a calculator-like
823 keypad, that keyboard isn't all that fun to use. */
824 ret = rb->do_menu(&r_to_c_menu_tol, &menu_selection_tol,
825 NULL, false);
826 if(ret<0) break;
828 switch(menu_selection_tol) {
829 case 0: /* 5% */
830 fourth_band = RES_GOLD;
831 break;
832 case 1: /* 10% */
833 fourth_band = RES_SILVER;
834 break;
835 case 2: /* 1% */
836 fourth_band = RES_BROWN;
837 break;
838 case 3: /* 2% */
839 fourth_band = RES_RED;
840 break;
841 case 4: /* 20% */
842 fourth_band = RES_NONE;
843 break;
846 kbd_input_int = rb->atoi(kbd_buffer);
847 in_resistance_int = kbd_input_int;
849 switch(menu_selection) {
850 case 0:
851 power_ten=0;
852 units_used = RES_BLACK;
853 break;
854 case 1: /* KOhms */
855 power_ten=3;
856 units_used = RES_ORANGE;
857 break;
858 case 2: /* MOhms */
859 power_ten=6;
860 units_used = RES_BLUE;
861 break;
862 case 3: /* GOhms */
863 power_ten=9;
864 units_used = RES_WHITE;
865 break;
868 temp=kbd_input_int;
869 while(temp>=100) {
870 temp/=10;
871 power_ten++;
873 first_band_int=temp/10;
874 second_band_int=temp%10;
876 first_band = get_band_rtoc(first_band_int);
877 second_band = get_band_rtoc(second_band_int);
878 multiplier = get_band_rtoc(power_ten);
880 if( first_band == RES_INVALID
881 || second_band == RES_INVALID
882 || multiplier == RES_INVALID) {
883 rb->splashf(HZ, "%d %s can not be represented",
884 in_resistance_int,band_data[units_used].unit);
885 return;
888 rb->lcd_clear_display();
889 lineno = INITIAL_TEXT_Y;
890 #ifndef USE_TEXT_ONLY
891 draw_resistor(first_band, second_band, multiplier, fourth_band);
892 #endif
893 draw_resistor_text(first_band, second_band, multiplier, fourth_band);
895 rb->snprintf(out_str, sizeof(out_str), "Input: %d %s", in_resistance_int,
896 band_data[units_used].unit);
897 display->set_viewport(&text_vp);
898 rb->lcd_puts_scroll(r_to_c_out_str_x, lineno++, out_str);
899 rb->lcd_update();
901 button_press = rb->button_get(true);
902 switch(button_press) {
903 case PLA_SELECT:
904 break;
905 default:
906 quit = true;
907 backlight_use_settings();
908 break;
911 display->set_viewport(&text_vp);
912 rb->lcd_stop_scroll();
913 display->set_viewport(&screen_vp);
914 rb->lcd_clear_display();
917 static void color_to_resistance(void)
919 backlight_force_on();
920 bool quit = false;
921 int button_input = 0;
923 /* The colors of the bands */
924 enum color first_band = 0;
925 enum color second_band = 0;
926 enum color third_band = 0;
927 enum color fourth_band = 0;
929 int total_resistance_centiunits = 0;
930 char total_resistance_str [35];
932 rb->splash(HZ/2, "Colour to resistance");
933 rb->lcd_clear_display();
935 while(!quit) {
936 first_band = do_first_band_menu();
937 if(first_band==RES_INVALID) break;
939 second_band = do_second_band_menu();
940 if(second_band==RES_INVALID) break;
942 third_band = do_third_band_menu();
943 if(third_band==RES_INVALID) break;
945 fourth_band = do_fourth_band_menu();
946 if(third_band==RES_INVALID) break;
948 total_resistance_centiunits = calculate_resistance(first_band,
949 second_band,
950 third_band);
952 rb->lcd_clear_display();
953 lineno = INITIAL_TEXT_Y;
954 #ifndef USE_TEXT_ONLY
955 draw_resistor(first_band, second_band, third_band, fourth_band);
956 #endif
957 draw_resistor_text(first_band, second_band, third_band, fourth_band);
959 if(total_resistance_centiunits % 100 == 0) {
960 /* No decimals */
961 rb->snprintf(total_resistance_str, sizeof(total_resistance_str),
962 "Resistance: %d %s",
963 total_resistance_centiunits/100,
964 unit_abbrev);
966 else {
967 rb->snprintf(total_resistance_str, sizeof(total_resistance_str),
968 "Resistance: %d.%2.2d %s",
969 total_resistance_centiunits/100,
970 total_resistance_centiunits%100,
971 unit_abbrev);
973 display->set_viewport(&text_vp);
974 rb->lcd_puts_scroll(total_resistance_str_x, lineno++,
975 total_resistance_str);
976 rb->lcd_puts_scroll(tolerance_str_x, lineno++,
977 get_tolerance_str(fourth_band));
978 rb->lcd_update();
980 button_input = rb->button_get(true);
981 switch(button_input) {
982 case PLA_RIGHT:
983 break;
984 case PLA_EXIT:
985 case PLA_SELECT:
986 default:
987 quit = true;
988 backlight_use_settings();
989 break;
992 display->set_viewport(&text_vp);
993 rb->lcd_stop_scroll();
994 display->set_viewport(&screen_vp);
995 rb->lcd_clear_display();
996 return;
999 enum plugin_status plugin_start(const void* nothing)
1001 (void)nothing;
1002 rb->lcd_clear_display();
1003 rb->lcd_update();
1004 int main_menu_selection = 0;
1005 bool menuquit = false;
1007 display = rb->screens[0];
1008 rb->viewport_set_defaults(&screen_vp,0);
1009 rb->viewport_set_defaults(&text_vp,0);
1010 rb->viewport_set_defaults(&bitmap_vp,0);
1011 #ifndef USE_TEXT_ONLY
1012 bitmap_vp.y = RESISTOR_BMP_Y + screen_vp.y;
1013 bitmap_vp.height = BMPHEIGHT_resistor;
1014 text_vp.y = bitmap_vp.y + bitmap_vp.height;
1015 text_vp.height = screen_vp.height - text_vp.y;
1016 #endif
1018 MENUITEM_STRINGLIST(main_menu, "Resistor Code Calculator:", NULL,
1019 "Colours -> Resistance", "Resistance -> Colours",
1020 "LED resistor calculator", "Help", "Exit");
1021 while (!menuquit) {
1022 display->set_viewport(&screen_vp);
1023 main_menu_selection = rb->do_menu(&main_menu, &main_menu_selection,
1024 NULL, false);
1025 switch(main_menu_selection) {
1026 case 0:
1027 color_to_resistance();
1028 break;
1029 case 1:
1030 resistance_to_color();
1031 break;
1032 case 2:
1033 led_resistance_calc();
1034 break;
1035 case 3:
1036 display_helpfile();
1037 break;
1038 case 4:
1039 menuquit = true;
1040 break;
1041 case MENU_ATTACHED_USB:
1042 return PLUGIN_USB_CONNECTED;
1045 return PLUGIN_OK;