Just a thought.... Is there an RPi setting that might force it to allocate a certain USB device (identified by it's serial number) to a certain port ?
I am not a Linux expert, and do not want be, but their probably is something along those lines, I would think. I do not want to spend many hours or days trying to figure that one out. The stuff I am doing is prototyping, not trying to find out the fine details of how an OS supposed to work.
I decided to revisit this project, and I noticed that some changes have been made to the functions collection, yes some have been added, but I found one that disappeared, dt_copy(). That one alone is putting a big dent in all of the previous programs that I have uploaded.
This concerns me because I try to use existing functions that are available in the accompanying libraries. The other thing that I noticed is the way the datetime functions are being used, if you ever had to set the time on a digital watch, you will be very comfortable with the new scheme. I guess code to work with the battery did not make it. I wonder what else has changed?
I am taking a different approach. This is an example of what may work for you. In my own version I will be adding a datetime that runs constantly on the bottom line, and probably a few more enhancements. Now you will be able to add your own ideas, all the functions are available, in the new library, if not, build your own, all of this is easy peasy.
It was suggested, in another thread, that I (we) should take a more DIY approach, so in the spirit of that suggestion, I guess everybody should just "do it yourself" from this point on. Remember it is easy peasy. Also remember this is PropGCC.
Ray
/*
firmbase2.c
November 27, 2015
* Basic setup
* Name, menu system, get battery volts
*/
#include "simpletools.h"
#include "badgetools.h"
/* Name to be displayed on Badge.*/
char f_name[] = "John";
char l_name[] = "Doe";
/**********/
/* Voltage gauge */
float calcVt(float batteryVolts, int decayMicros);
float batVolts(float vt);
float RC = 360000.0 * (1.0 / 100000000.0);
float vt,vbat;
/**********/
/* Glabal variables */
int states;
/* Declarations */
void Menu();
void DisplayName();
void Sys_Volts();
int main()
{
// Add startup code here.
badge_setup();
cursor(0,0);
text_size(SMALL);
oledprint("OSH btn for menu");
pause(2000);
displayName();
while(1)
{
// Add main loop code here.
if (button(6) == 1) // Btn OSH pressed
{
Menu();
pause(1000);
}
}
}
void Menu()
{
while(1)
{
while(!buttons());
clear();
cursor(0,0);
text_size(SMALL);
oledprint("Main Menu");
cursor(0,1);
oledprint("P17-Voltage ");
cursor(0,6);
oledprint("OSH to exit");
while((states = buttons()) == 0);
switch(states)
{
/* Add button functions here. */
case 0b0100000: // P17
Sys_Volts();
pause(500);
continue;
case 0b1000000:
break; // Leave menu
}
displayName(); // Clear the menu screen, display name.
break; // Get out of while loop, and leave Menu().
}
}
/* Didplay the selected name. */
void displayName()
{
clear();
text_size(LARGE);
cursor(0,0);
/* Your name, do not exceed 16 characters.*/
oledprint(f_name);
cursor(0,1);
oledprint(l_name);
}
/* Display the battery voltage on the bottom line. */
void Sys_Volts()
{
vt = calcVt(4.17, 1453); // This is using the universal value.
/* Show voltage */
cursor(0,7); // Bottom line, SMALL text.
//Voltage
vbat = batVolts(vt);
pause(100);
oledprint("Voltage - %1.2f V", vbat);
}
/* Voltage calculations */
float calcVt(float voltsBattery, int microDecay)
{
float voltsThreshold, tDecay;
tDecay = ((float) microDecay) / 1000000.0;
voltsThreshold = voltsBattery * (1 - exp(-tDecay / RC));
return voltsThreshold;
}
float batVolts(float voltsThreshold)
{
float voltsBattery, microsDecay;
low(0);
pause(1);
microsDecay = ((float) rc_time(0, 0)) / 1000000.0;
voltsBattery = voltsThreshold / (1 - exp(-microsDecay / RC));
return voltsBattery;
}
/**********/
Easy peasy. This is PropGCC code. I decided to do a variation on the Set Time example.
Basically the Badge always displays the name you chose, at that screen you can show a current time, date, and voltage for the Badge. You can also do a sub menu that lets you do the set current date and time.
From this point it can get very messy trying to insert sub menus to do things like send and receive via IR, store things to the EEPROM, ..., etc. You will have to have a very good grasp on how to use the menu system, plus available RAM, and still have your program work, correctly.
Since I have a Staff and Guest Badge, I will probably set up the Staff to also send the date and time. On the Guest Badge, probably just have a receive date and time.
Since the program has a set time and date functionality, I decided not to go with the constant clock displaying on the bottom line. But it would be interesting to add a COG that checks the battery voltage status, and then maybe lights up an RGB when the battery needs to find a charger.
I am not using the Zip Project function because I have to see why the last time I used it not all of the project files got included and there was something wrong with the program itself.
Ray
/*
stControl1.c
November 29, 2015
Variation on Set Time example.
* Display name, set time and day, view current date,
* view current time, view system voltage
*/
#include "simpletools.h"
#include "badgetools.h" // Include badgetools library
#include "datetime.h" // Include datetime library
datetime dt = {2015, 1, 1, 0, 0, 0}; // Set up the date/time
char dates[9]; // Stores date string
char times[9]; // Stores time string
/* Voltage gauge */
float calcVt(float batteryVolts, int decayMicros);
float batVolts(float vt);
float RC = 360000.0 * (1.0 / 100000000.0);
float vt,vbat;
/**********/
/* Name to be displayed on Badge.
Add your preffered name here. */
char f_name[] = "System";
char l_name[] = "Control";
/**********/
// Forward declarations
// General
void displayName(void);
void bigVolts(void);
// Time and Date
void setYear(void);
void setMonth(void);
void setDay(void);
void setHour(void);
void setMinute(void);
void setSecond(void);
void menu(void);
void submenu(void);
void main() // Main function
{
badge_setup(); // Start badge systems
dt_run(dt); // Start system timer with dt
clear();
text_size(SMALL);
oledprint("OSH for SET menu"); // Message how to set w/ OSH
cursor(0,1);
oledprint("P17-TimeP27-Date");
cursor(0,2);
oledprint("P16-Volts");
pause(2000);
displayName();
while(1) // Main loop
{
dt = dt_get(); // Get system time
dt_toDateStr(dt, dates); // Convert to strings
dt_toTimeStr(dt, times);
//cursor(0, 0); // Position cursor
//oledprint("%s%s", dates, times); // Display date/time
//pause(100); // Wait .1 s before repeating
if (button(0) == 1) // P27 - date
{
cursor(0,0);
oledprint("%s", dates);
pause(2000);
displayName();
}
if (button(5) == 1) // P17 - Time
{
cursor(0,0);
oledprint("%s", times);
pause(2000);
displayName();
}
if (button(4) == 1) // P16 - Volts
{
bigVolts();
pause(2000);
displayName();
}
if(button(6) == 1) // If OSH pressed...
{
menu(); // Display menu
pause(1000); // 1 s to let go of button
int states = 0; // States variable
while(states == 0) // Wait for button press
{
states = buttons(); // Keep checking
}
states = 0; // Clear the states
while(states != 0b1000000)
{
states = buttons(); // Check buttons
switch(states) // Handle each case
{
case 0b0100000: // P17 set year
print("year\n");
setYear();
break;
case 0b0010000: // P16 set month
setMonth();
break;
case 0b0001000: // P15 set day
setDay();
break;
case 0b0000100: // P25 set hour
setHour();
break;
case 0b0000010: // P26 set minute
setMinute();
break;
case 0b0000001: // P27 set second
setSecond();
break;
case 0b1000000: // OSH save and exit
dt_set(dt);
displayName();
break;
}
}
}
}
}
void menu(void) // Display buttons menu
{
clear();
text_size(SMALL);
cursor(0, 0);
oledprint("P17-Yr");
cursor(0, 3);
oledprint("P16-Mon");
cursor(0, 6);
oledprint("P15-Day");
cursor(10, 6);
oledprint("P25-Hr");
cursor(9, 3);
oledprint("P26-Min");
cursor(9, 0);
oledprint("P17-Sec");
cursor(4, 7);
oledprint("OSH-Done");
text_size(LARGE);
}
void submenu(void) // Display time set menu
{
text_size(SMALL);
cursor(9, 0);
oledprint("P27-UP");
cursor(12, 3);
oledprint("P26");
cursor(11, 4);
oledprint("NEXT");
cursor(9, 7);
oledprint("P25-DN");
text_size(LARGE);
}
void setYear(void) // Year setting function
{
clear(); // Clear display
oledprint("YEAR"); // Display year
submenu(); // Display button submenu
int y = dt.y; // Temp copy of dt.y to y
cursor(0, 1); // Cursor -> row 0, col 1
oledprint("%d", y); // Display current year
pause(1000); // 1 s for letting go of
// previous button
while(1) // Setting loop
{
int states = buttons(); // Check buttons
if(states == 0b0000001) // If P27
{
y++; // Add 1 to year
}
else if(states == 0b0000100) // If P25
{
y--; // Subtract 1 from year
}
else if(states == 0b0000010) // If P26
{
dt.y = y; // Copy y back to dt.y
break; // Break from while loop
}
text_size(LARGE); // Back to large text
cursor(0, 1); // Cursor at bottom-left
oledprint("%d", y); // Update year display
pause(100); // Wait .1 s
}
menu(); // Back to menu
return; // Return from function
}
void setMonth(void) // Similar to setYear
{ // See setYear for comments
clear();
text_size(LARGE);
oledprint("MON");
submenu();
int mo = dt.mo;
cursor(0, 1);
oledprint("%02d", mo);
pause(1000);
while(1)
{
int states = buttons();
if(states == 0b0000001)
{
mo++;
if(mo > 12) mo = 1;
}
else if(states == 0b0000100)
{
mo--;
if(mo < 1) mo = 12;
}
else if(states == 0b0000010)
{
dt.mo = mo;
break;
}
text_size(LARGE);
cursor(0, 1);
oledprint("%02d", mo);
pause(100);
}
menu();
return;
}
void setDay(void) // Similar to setYear
{ // See setYear for comments
clear();
text_size(LARGE);
cursor(0, 0);
oledprint("DAY");
submenu();
int d = dt.d;
cursor(0, 1);
oledprint("%02d", d);
while(1)
{
int states = buttons();
if(states == 0b0000001)
{
d++;
if(d > 31) d = 1;
}
else if(states == 0b0000100)
{
d--;
if(d < 1) d = 31;
}
else if(states == 0b0000010)
{
dt.d = d;
break;
}
text_size(LARGE);
cursor(0, 1);
oledprint("%02d", d);
pause(100);
}
menu();
return;
}
void setHour(void) // Similar to setYear
{ // See setYear for comments
clear();
text_size(LARGE);
oledprint("HOUR");
submenu();
int h = dt.h;
cursor(0, 1);
oledprint("%02d", h);
pause(1000);
while(1)
{
int states = buttons();
if(states == 0b0000001)
{
h++;
if(h > 23) h = 0;
}
else if(states == 0b0000100)
{
h--;
if(h < 0) h = 23;
}
else if(states == 0b0000010)
{
dt.h = h;
break;
}
text_size(LARGE);
cursor(0, 1);
oledprint("%02d", h);
pause(100);
}
menu();
return;
}
void setMinute(void) // Similar to setYear
{ // See setYear for comments
clear();
text_size(LARGE);
oledprint("MIN");
submenu();
int m = dt.m;
cursor(0, 1);
oledprint("%02d", m);
pause(1000);
while(1)
{
int states = buttons();
if(states == 0b0000001)
{
m++;
if(m > 59) m = 0;
}
else if(states == 0b0000100)
{
m--;
if(m < 0) m = 59;
}
else if(states == 0b0000010)
{
dt.m = m;
break;
}
text_size(LARGE);
cursor(0, 1);
oledprint("%02d", m);
pause(100);
}
menu();
return;
}
void setSecond(void) // Similar to setYear
{ // See setYear for comments
clear();
text_size(LARGE);
oledprint("SEC");
submenu();
int s = dt.s;
cursor(0, 1);
oledprint("%02d", s);
pause(1000);
while(1)
{
int states = buttons();
if(states == 0b0000001)
{
s++;
if(s > 59) s = 0;
}
else if(states == 0b0000100)
{
s--;
if(s < 0) s = 59;
}
else if(states == 0b0000010)
{
dt.s = s;
break;
}
text_size(LARGE);
cursor(0, 1);
oledprint("%02d", s);
pause(100);
}
menu();
return;
}
void displayName(void)
{
clear();
text_size(LARGE);
cursor(0,0);
/* Your name, do not exceed 16 characters.*/
oledprint(f_name);
cursor(0,1);
oledprint(l_name);
}
void bigVolts(void)
{
vt = calcVt(4.17, 1453); // This is using the universal value.
/* Show voltage */
clear();
text_size(LARGE);
//Voltage
vbat = batVolts(vt);
pause(100);
oledprint("%1.2f V", vbat);
}
/* Voltage calculations */
float calcVt(float voltsBattery, int microDecay)
{
float voltsThreshold, tDecay;
tDecay = ((float) microDecay) / 1000000.0;
voltsThreshold = voltsBattery * (1 - exp(-tDecay / RC));
return voltsThreshold;
}
float batVolts(float voltsThreshold)
{
float voltsBattery, microsDecay;
low(0);
pause(1);
microsDecay = ((float) rc_time(0, 0)) / 1000000.0;
voltsBattery = voltsThreshold / (1 - exp(-microsDecay / RC));
return voltsBattery;
}
/**********/
After doing the slight modification of the set time program, I am getting a little concerned about the complexity of the menu system that is available.
In order to get some decent functionality out of the Badge, it will have to have an extensive, and maybe complex menu system. I am not sure if doing the complex menu system in Spin would be any easier though, in fact you just might run out of memory very quickly, but that is a guess on my part. So far, using the CMM method, it seems like the RAM usage is at about 50%, so that is not too bad.
Any comments about this concern, is it anything to worry about in the short term?
As an interesting diversion, how would one go about using PASM to work with the Badge.
I know we have the PASM example, in the manual, for blinking an LED attached to P16, I guess you could try that with one of the LEDs on the Badge. But how would you go about using PASM to work with the OLED unit on the Badge? I suppose somebody would have to come up with a driver for it. Does Parallax have PASM drivers for the thingies on the Badge?
In the long run how efficient would it be to use only PASM to accomplish what is available with the C, or for that matter, Spin examples? We always have a small group of forum members talking about how well PASM/Spin works for the Propeller, maybe this could be an interesting experiment, use strictly PASM program(s) to use the Hackable Badge. Practice what you preach, I guess.
Not sure how using PropBASIC would help in using PASM for the Badge. You would still need drivers in PropBASIC to use the components on the Badge. And the last time I used PropBASIC, I remember that the PASM code that was produced, was not that clear and concise.
The other problem with PropBASIC, to much of a hassle to setup, so you can run it.
Not really. The only thing that OLED object does (I didn't write it) is transfer the buffer to the OLED using PASM; the rest is in Spin and a bit slow. I'm working on a pure PASM OLED driver now.
Not sure how using PropBASIC would help in using PASM for the Badge.
The point I was trying to make, was that if YOU wanted to learn to write PASM code for your badge, then using PropBASIC as an intermediary language "might" help simplify the learning task. Obviously, if you are asking for someone else to produce the code, then you are correct in your thoughts- that using another language (such as PropBASIC) will likely not help achieve that!
If he has time to work on converting some of the Spin code to PASM, then Jon "CodeMaster" Mac will sure be your best bet!
I was just trying to be helpful and offer ideas whist trying to respond in context with your comments- such as "I suppose somebody would have to come up with a driver for it.". I'd hoped to be going to a happy place; not somewhere you might not like to be.
Your probably right about taking a break- I guess I need one too! It's been an intense year and so the holidays fast approaching are most welcome. Time to spend some time with family and switch off the soldering iron for a few days.
Comments
Just a thought.... Is there an RPi setting that might force it to allocate a certain USB device (identified by it's serial number) to a certain port ?
Ray
This concerns me because I try to use existing functions that are available in the accompanying libraries. The other thing that I noticed is the way the datetime functions are being used, if you ever had to set the time on a digital watch, you will be very comfortable with the new scheme. I guess code to work with the battery did not make it. I wonder what else has changed?
Ray
It was suggested, in another thread, that I (we) should take a more DIY approach, so in the spirit of that suggestion, I guess everybody should just "do it yourself" from this point on. Remember it is easy peasy. Also remember this is PropGCC.
Ray
Basically the Badge always displays the name you chose, at that screen you can show a current time, date, and voltage for the Badge. You can also do a sub menu that lets you do the set current date and time.
From this point it can get very messy trying to insert sub menus to do things like send and receive via IR, store things to the EEPROM, ..., etc. You will have to have a very good grasp on how to use the menu system, plus available RAM, and still have your program work, correctly.
Since I have a Staff and Guest Badge, I will probably set up the Staff to also send the date and time. On the Guest Badge, probably just have a receive date and time.
Since the program has a set time and date functionality, I decided not to go with the constant clock displaying on the bottom line. But it would be interesting to add a COG that checks the battery voltage status, and then maybe lights up an RGB when the battery needs to find a charger.
I am not using the Zip Project function because I have to see why the last time I used it not all of the project files got included and there was something wrong with the program itself.
Ray
In order to get some decent functionality out of the Badge, it will have to have an extensive, and maybe complex menu system. I am not sure if doing the complex menu system in Spin would be any easier though, in fact you just might run out of memory very quickly, but that is a guess on my part. So far, using the CMM method, it seems like the RAM usage is at about 50%, so that is not too bad.
Any comments about this concern, is it anything to worry about in the short term?
Ray
I know we have the PASM example, in the manual, for blinking an LED attached to P16, I guess you could try that with one of the LEDs on the Badge. But how would you go about using PASM to work with the OLED unit on the Badge? I suppose somebody would have to come up with a driver for it. Does Parallax have PASM drivers for the thingies on the Badge?
In the long run how efficient would it be to use only PASM to accomplish what is available with the C, or for that matter, Spin examples? We always have a small group of forum members talking about how well PASM/Spin works for the Propeller, maybe this could be an interesting experiment, use strictly PASM program(s) to use the Hackable Badge. Practice what you preach, I guess.
Ray
That compiles to PASM, so you could write in Basic then view the output PASM code (and build a library).
I've not got into doing conversions, but I've heard talk of people converting spin and/or C code to Basic in the past. Albeit a manual process.
The other problem with PropBASIC, to much of a hassle to setup, so you can run it.
Ray
The point I was trying to make, was that if YOU wanted to learn to write PASM code for your badge, then using PropBASIC as an intermediary language "might" help simplify the learning task. Obviously, if you are asking for someone else to produce the code, then you are correct in your thoughts- that using another language (such as PropBASIC) will likely not help achieve that!
If he has time to work on converting some of the Spin code to PASM, then Jon "CodeMaster" Mac will sure be your best bet!
Ray
I was just trying to be helpful and offer ideas whist trying to respond in context with your comments- such as "I suppose somebody would have to come up with a driver for it.". I'd hoped to be going to a happy place; not somewhere you might not like to be.
Your probably right about taking a break- I guess I need one too! It's been an intense year and so the holidays fast approaching are most welcome. Time to spend some time with family and switch off the soldering iron for a few days.
Happy Holidays to you too.
Michael.