From 2d4b879b60f6f9243e51bc49b3f0b0f9a7268720 Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Tue, 22 Mar 2011 16:06:11 -0600 Subject: [PATCH] Added Ohm's Law feature to resistor.c plugin --- apps/plugins/resistor.c | 297 +++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 286 insertions(+), 11 deletions(-) diff --git a/apps/plugins/resistor.c b/apps/plugins/resistor.c index 8676c37..2ab474d 100644 --- a/apps/plugins/resistor.c +++ b/apps/plugins/resistor.c @@ -50,6 +50,7 @@ TODO: #define tolerance_str_x 1 #define resistance_val_x 1 #define r_to_c_out_str_x 1 +#define ohm_low_out_str_x 1 #define INITIAL_TEXT_Y 0 @@ -523,10 +524,11 @@ static void display_helpfile(void) /* -- */ "", "How to use this calculator", "", /* 3 */ /* -- */ - "This", "calculator", "has", "three", "modes:", "", + "This", "calculator", "has", "four", "modes:", "", "Resistance", "to", "colour", "codes,", "", - "Colour", "codes", "to", "resistance", "", - "and", "LED", "resistance", "calculator", "", "", + "Colour", "codes", "to", "resistance,", "", + "LED", "resistance", "calculator", "", + "and", "Ohm's", "Law", "calculator", "", /* -- */ "At", "this", "time", "there", "is", "only", "support", "for", "four-", "band", "resistors.", "", "", @@ -553,8 +555,13 @@ static void display_helpfile(void) "current", "that", "it", "will", "draw", "(likewise", "with", "the", "first", "option).", "Then", "use", "the", "onscreen", "keyboard", "to", "type", "in", "the", "supply", "voltage", "and,", "if", "selected,", - "the", "custom", "foreward", "current.", "", - "Disclaimer:", "this", + "the", "custom", "foreward", "current.", "", "", + /* -- */ + "Ohm's", "Law", "calculator", "mode", "is", "used", "to determin", "how", + "much" "voltage,", "current,", "resistance", "and power", "is", + "associated", "with", "a", "component", "given", "any", "two", "values.", + "", "", + "Disclaimer:", "this", "calculator", "produces", "safe", "estimates,", "but", "use", "your", "own", "judgement", "when", "using", "these", "output", "values.", "Power", "rating", "and", "displayed", "resistance", "are", "rounded", @@ -571,7 +578,271 @@ static void display_helpfile(void) NULL, true); return; } - + +double resistor_abs(double val) +{ + if(val < 0) + return -val; + else + return val; +} + +double resistor_sqrt(double square) +{ + int k = 0; + double temp = 0; + double root = resistor_abs(square+1)/2; + + while( abs(root - temp) > 0.000000000001 ){ + temp = root; + root = (square/temp + temp)/2; + k++; + if (k>10000) return 0; + } + + return root; +} + +double str_to_double(char * num_str) +{ + int numint = rb->atoi(num_str); + int numdec = 0; + int num_didgets = 0; + double num; + double dec; + bool after_dec = false; + + /* Get the decimal part */ + while(*num_str != '\0') { + if(*num_str == '.') { + num_str++; + numdec = rb->atoi(num_str); + after_dec = true; + } else if(after_dec) { + num_didgets++; + num_str++; + } else { + num_str++; + + } + } + + /* Turn the decimal part into an actual decimal */ + dec = numdec; + for(int i = 0; i < num_didgets; i++) { + dec/=10; + } + + /* Return the sum of the integer and decimal parts */ + num = numint + dec; + return num; +} + +static void ohms_law(void) +{ + backlight_ignore_timeout(); + double voltage = 0; + double current = 0; + double resistance = 0; + double power; + + int first_menu_selection; + int second_menu_selection; + int button_press; + + int vint; + int cint; + int rint; + int pint; + int vdec; + int cdec; + int rdec; + int pdec; + + double first_number; + double second_number; + + bool bad_value_given = false; + bool quit = false; + char kbd_buffer [10]; + char volt_str[30]; + char curr_str[30]; + char res_str[30]; + char pow_str[30]; + + rb->lcd_clear_display(); + + MENUITEM_STRINGLIST(first_menu, "First Value", NULL, + "Voltage", "Current", + "Resistance", "Power"); + MENUITEM_STRINGLIST(second_menu, "Second Value", NULL, + "Voltage", "Current", + "Resistance", "Power"); + + while(!quit) { + /* First menu */ + first_menu_selection = rb->do_menu(&first_menu, + &first_menu_selection, NULL, false); + if(first_menu_selection<0 ) break; + + rb->splash(HZ*2, "First Value"); + memset(kbd_buffer,0,sizeof(kbd_buffer)); + rb->kbd_input(kbd_buffer, sizeof(kbd_buffer)); + first_number = str_to_double(kbd_buffer); + + /* Second menu */ + second_menu_selection = rb->do_menu(&second_menu, + &second_menu_selection, NULL, false); + if(second_menu_selection<0 ) break; + + rb->splash(HZ*2, "Second Value"); + memset(kbd_buffer,0,sizeof(kbd_buffer)); + rb->kbd_input(kbd_buffer, sizeof(kbd_buffer)); + second_number = str_to_double(kbd_buffer); + + /* Handle Calculations */ + switch(first_menu_selection) { + case 0: /* V */ + voltage = first_number; + switch(second_menu_selection) { + case 0: /* V */ + bad_value_given = true; + break; + case 1: /* I */ + current = second_number; + resistance = voltage/current; + power = voltage*current; + break; + case 2: /* R */ + resistance = second_number; + current = voltage/resistance; + power = voltage*voltage/resistance; + break; + case 3: /* P */ + power = second_number; + current = power/voltage; + resistance = voltage*voltage/power; + break; + } + break; + case 1: /* I */ + current = first_number; + switch(second_menu_selection) { + case 0: /* V */ + voltage = second_number; + resistance = voltage/current; + power = voltage*current; + break; + case 1: /* I */ + bad_value_given = true; + break; + case 2: /* R */ + resistance = second_number; + voltage = current*resistance; + power = current*current*resistance; + break; + case 3: /* P */ + power = second_number; + voltage = power/current; + resistance = power/(current*current); + break; + } + break; + case 2: /* R */ + resistance = first_number; + switch(second_menu_selection) { + case 0: /* V */ + voltage = second_number; + current = voltage/resistance; + power = voltage*voltage/resistance; + break; + case 1: /* I */ + current = second_number; + voltage = current*resistance; + power = current*current*resistance; + break; + case 2: /* R */ + bad_value_given = true; + break; + case 3: /* P */ + power = second_number; + voltage = resistor_sqrt(power*resistance); + current = resistor_sqrt(power/resistance); + break; + } + break; + case 3: /* P */ + power = first_number; + switch(second_menu_selection) { + case 0: /* V */ + voltage = second_number; + current = power/voltage; + resistance = voltage*voltage/power; + break; + case 1: /* I */ + current = second_number; + voltage = power/current; + resistance = power/(current*current); + break; + case 2: /* R */ + voltage = second_number; + voltage = resistor_sqrt(power*resistance); + current = resistor_sqrt(power/resistance); + break; + case 3: /* P */ + bad_value_given = true; + break; + } + break; + } + rb->lcd_clear_display(); + + if(bad_value_given) { + rb->splash(HZ*2, "Same value given twice."); + break; + } + + vint = voltage; + cint = current; + rint = resistance; + pint = power; + + vdec = (voltage - vint)*100000; + cdec = (current - cint)*100000; + rdec = (resistance - rint)*100000; + pdec = (power - pint)*100000; + + rb->snprintf(volt_str, 30, "Voltage: %d.%d V", vint, vdec); + rb->snprintf(curr_str, 30, "Current: %d.%d A", cint, cdec); + rb->snprintf(res_str, 30, "Resistance: %d.%d Ohm", rint, rdec); + rb->snprintf(pow_str, 30, "Power: %d.%d W", pint, pdec); + + lineno = INITIAL_TEXT_Y; + + /* display->set_viewport(&text_vp); */ + rb->lcd_puts_scroll(ohm_low_out_str_x, lineno++, volt_str); + rb->lcd_puts_scroll(ohm_low_out_str_x, lineno++, curr_str); + rb->lcd_puts_scroll(ohm_low_out_str_x, lineno++, res_str); + rb->lcd_puts_scroll(ohm_low_out_str_x, lineno++, pow_str); + rb->lcd_update(); + + button_press = rb->button_get(true); + button_press = rb->button_get(true); + switch(button_press) { + case PLA_SELECT: + break; + default: + quit = true; + backlight_use_settings(); + break; + } + } + display->set_viewport(&text_vp); + rb->lcd_stop_scroll(); + display->set_viewport(&screen_vp); + rb->lcd_clear_display(); +} + static void led_resistance_calc(void) { backlight_ignore_timeout(); @@ -594,7 +865,7 @@ static void led_resistance_calc(void) char power_rating_out_str [40]; int power_ten, first_band_int, second_band_int = 0; - + enum color first_band; enum color second_band; enum color multiplier; @@ -664,7 +935,7 @@ static void led_resistance_calc(void) foreward_current = ((rb->atoi(fwd_kbd_buffer))/10); break; } - + if(foreward_current == 0) break; rb->lcd_clear_display(); @@ -1017,7 +1288,7 @@ enum plugin_status plugin_start(const void* nothing) MENUITEM_STRINGLIST(main_menu, "Resistor Code Calculator:", NULL, "Colours -> Resistance", "Resistance -> Colours", - "LED resistor calculator", "Help", "Exit"); + "LED resistor calculator", "Ohm's Law", "Help", "Exit"); while (!menuquit) { display->set_viewport(&screen_vp); main_menu_selection = rb->do_menu(&main_menu, &main_menu_selection, @@ -1032,10 +1303,13 @@ enum plugin_status plugin_start(const void* nothing) case 2: led_resistance_calc(); break; - case 3: + case 3: + ohms_law(); + break; + case 4: display_helpfile(); break; - case 4: + case 5: menuquit = true; break; case MENU_ATTACHED_USB: @@ -1044,3 +1318,4 @@ enum plugin_status plugin_start(const void* nothing) } return PLUGIN_OK; } + -- 1.7.1