C library for interfacing microcontroller and AT modem - gcc

I am working on some embedded system, where I use low-end uC, i.e. Atmega128.
My system also includes modem, driven via AT commands. I tried to look for any appropriate C library (for GCC), but couldn't find any. Although I know that putting "all" the possible AT command set into uC memory and so having "general purpose" library is unreasonable (and I just need around 30 commands for whole operation), I just need to get some suitable (i.e. lightweight, robust) control mechanism for handling transmitted and received UART strings in uC.
Does anybody know of any proven libraries or functions? Or maybe anyone could point me to some good resources/suggestions?

I hope you might be using this for the GSM or GPRS Modem interfacing, assuming as you have not specified application.
Brief : GSM, GPRS modem is also using AT command inteface for communication with external controller.
See detailed explanation here:
Microchip AN1373 - Using PIC32 MCUs to Develop GSM/GPRS/GPS Solutions
void UART_Buf(void)
{
ch=SCI2D;
if(rx_buffer[2] == 'O' && rx_buffer[3] =='K')
{
rx_buffer[5] = '\0';
msgindex=2; // code for OK
rx_wr_i=0;
}
if(rx_buffer[2] == 'B' && rx_buffer[3] =='U' && rx_buffer[4] == 'S' && rx_buffer[5] =='Y')
{
msgindex=3; // Code for Busy
rx_wr_i=0;
}
if(rx_buffer[2] == 'N' && rx_buffer[3] =='O' && rx_buffer[4] == ' ' && rx_buffer[5] =='C' && rx_buffer[6] =='A' && rx_buffer[7] =='R'&& rx_buffer[8] =='R' && rx_buffer[9] =='I' && rx_buffer[10] =='E' && rx_buffer[11] =='R')
{
msgindex=3; // Code for No Carrier
rx_wr_i=0;
}
if(rx_buffer[2] == 'E' && rx_buffer[3] =='R' && rx_buffer[4] == 'R' && rx_buffer[5] =='O' && rx_buffer[6] =='R' )
{
msgindex=4; // Code for Error
rx_wr_i=0;
}
if(rx_buffer[2]=='+' && rx_buffer[3]=='C' && rx_buffer[4] == 'M' && rx_buffer[5] =='S' )
{
msgindex=3;
}
if(rx_buffer[2]=='+' && rx_buffer[3]=='C' && rx_buffer[4] == 'M' && rx_buffer[5] =='E' )
{
msgindex=3;
}
if(rx_buffer[2]=='+' && rx_buffer[3]=='C' && rx_buffer[4] == 'M' && rx_buffer[5] =='G' && rx_buffer[6]== 'R')
{
msgindex=6;
}
if(rx_buffer[2]=='E' && rx_buffer[3]=='R' && rx_buffer[4] == 'R' && rx_buffer[5] =='O' && rx_buffer[6] == 'R')
{
msgindex=3;
}
if(rx_buffer[2]=='+' && rx_buffer[3]=='C' && rx_buffer[4] == 'S' && rx_buffer[5] =='Q' )
{
msgindex=7;
}
if(rx_buffer[2]=='+' && rx_buffer[3]=='C' && rx_buffer[4] == 'O' && rx_buffer[5] =='L'&& rx_buffer[6] =='P' )
{
msgindex=8;
}
if(ch == '\r')
linefeed++;
}
and in ISR
__interrupt void isrVsci2rx(void)
{
SCI2S1_RDRF = 0;
rx_buffer[rx_ack++]= SCI2D;
if(rx_ack>RX_BUFFER_MASK)
rx_ack=0;
UART_Buf();
rx_length++;
}
check msgindex and linefeed to know response received.

Related

Xcode slow compile time on equatable protocol

Xcode is taking too long to compile class's with equatable protocol, this is a little strange because in this particular case it's only comparing primitive types, this should be easy.
Took 608ms to type-check this:
public static func == (lhs: TheModel, rhs: TheModel) -> Bool {
return lhs.firstName == rhs.firstName &&
lhs.lastName == rhs.lastName &&
lhs.maritalStatus == rhs.maritalStatus &&
lhs.sex == rhs.sex &&
lhs.birthDate == rhs.birthDate &&
lhs.nationality == rhs.nationality &&
lhs.hasAnotherNationality == rhs.hasAnotherNationality &&
lhs.anotherNationality == rhs.anotherNationality &&
lhs.nif == rhs.nif &&
lhs.hasAnotherFiscalAddress == rhs.hasAnotherFiscalAddress &&
lhs.identificationCard == rhs.identificationCard &&
lhs.identificationCardNumber == rhs.identificationCardNumber &&
lhs.identificationCardExpirationDate == rhs.identificationCardExpirationDate &&
lhs.education == rhs.education &&
lhs.jobTitle == rhs.jobTitle &&
lhs.patronalEntity == rhs.patronalEntity &&
lhs.hasLivesOfIncomes == rhs.hasLivesOfIncomes &&
lhs.permanentAddressContainer == rhs.permanentAddressContainer &&
lhs.fiscalAddressContainer == rhs.fiscalAddressContainer &&
lhs.placeOfBirth == rhs.placeOfBirth &&
lhs.honorificTitle == rhs.honorificTitle &&
lhs.userType == rhs.userType &&
lhs.userTypeDescription == rhs.userTypeDescription &&
lhs.lastVisitedCountryCode == rhs.lastVisitedCountryCode &&
lhs.lastUpdate == rhs.lastUpdate
}
PS:I know this comparison it's a little overkill but it's only an example.
By the way, this was in MacbookPro with core i9, 64Gb of RAM and SSD.
Update - I made some changes and run some more tests:
Test 1
Added explicit type to a let and returned the let: Took ~450ms
public static func == (lhs: TheModel, rhs: TheModel) -> Bool {
let extractedExpr: Bool = lhs.firstName == rhs.firstName &&
lhs.lastName == rhs.lastName &&
lhs.maritalStatus == rhs.maritalStatus &&
lhs.sex == rhs.sex &&
lhs.birthDate == rhs.birthDate &&
lhs.nationality == rhs.nationality &&
lhs.hasAnotherNationality == rhs.hasAnotherNationality &&
lhs.anotherNationality == rhs.anotherNationality &&
lhs.nif == rhs.nif &&
lhs.hasAnotherFiscalAddress == rhs.hasAnotherFiscalAddress &&
lhs.identificationCard == rhs.identificationCard &&
lhs.identificationCardNumber == rhs.identificationCardNumber &&
lhs.identificationCardExpirationDate == rhs.identificationCardExpirationDate &&
lhs.education == rhs.education &&
lhs.jobTitle == rhs.jobTitle &&
lhs.patronalEntity == rhs.patronalEntity &&
lhs.hasLivesOfIncomes == rhs.hasLivesOfIncomes &&
lhs.permanentAddressContainer == rhs.permanentAddressContainer &&
lhs.fiscalAddressContainer == rhs.fiscalAddressContainer &&
lhs.placeOfBirth == rhs.placeOfBirth &&
lhs.honorificTitle == rhs.honorificTitle &&
lhs.userType == rhs.userType &&
lhs.userTypeDescription == rhs.userTypeDescription &&
lhs.lastVisitedCountryCode == rhs.lastVisitedCountryCode &&
lhs.lastUpdate == rhs.lastUpdate
return extractedExpr
}
Test 2
Added parenthesis to each case: Same result as Test 1!
let extractedExpr: Bool = (lhs.firstName == rhs.firstName) &&
(lhs.lastName == rhs.lastName) &&
(lhs.maritalStatus == rhs.maritalStatus) &&
(lhs.sex == rhs.sex) &&
(lhs.birthDate == rhs.birthDate) &&
(lhs.nationality == rhs.nationality) &&
(lhs.hasAnotherNationality == rhs.hasAnotherNationality) &&
(lhs.anotherNationality == rhs.anotherNationality) &&
(lhs.nif == rhs.nif) &&
(lhs.hasAnotherFiscalAddress == rhs.hasAnotherFiscalAddress) &&
(lhs.identificationCard == rhs.identificationCard) &&
(lhs.identificationCardNumber == rhs.identificationCardNumber) &&
(lhs.identificationCardExpirationDate == rhs.identificationCardExpirationDate) &&
(lhs.education == rhs.education) &&
(lhs.jobTitle == rhs.jobTitle) &&
(lhs.patronalEntity == rhs.patronalEntity) &&
(lhs.hasLivesOfIncomes == rhs.hasLivesOfIncomes) &&
(lhs.permanentAddressContainer == rhs.permanentAddressContainer) &&
(lhs.fiscalAddressContainer == rhs.fiscalAddressContainer) &&
(lhs.placeOfBirth == rhs.placeOfBirth) &&
(lhs.honorificTitle == rhs.honorificTitle) &&
(lhs.userType == rhs.userType) &&
(lhs.userTypeDescription == rhs.userTypeDescription) &&
(lhs.lastVisitedCountryCode == rhs.lastVisitedCountryCode) &&
(lhs.lastUpdate == rhs.lastUpdate)
return extractedExpr
Test 3
Added a bollean array as var with explicity type and append each condition: Took 171ms :)
public static func == (lhs: TheModel, rhs: TheModel) -> Bool {
var result: [Bool] = [Bool]()
result.append(lhs.firstName == rhs.firstName)
result.append(lhs.lastName == rhs.lastName)
result.append(lhs.maritalStatus == rhs.maritalStatus)
result.append(lhs.sex == rhs.sex)
result.append(lhs.birthDate == rhs.birthDate)
result.append(lhs.nationality == rhs.nationality)
result.append(lhs.hasAnotherNationality == rhs.hasAnotherNationality)
result.append(lhs.anotherNationality == rhs.anotherNationality)
result.append(lhs.nif == rhs.nif)
result.append(lhs.hasAnotherFiscalAddress == rhs.hasAnotherFiscalAddress)
result.append(lhs.identificationCard == rhs.identificationCard)
result.append(lhs.identificationCardNumber == rhs.identificationCardNumber)
result.append(lhs.identificationCardExpirationDate == rhs.identificationCardExpirationDate)
result.append(lhs.education == rhs.education)
result.append(lhs.jobTitle == rhs.jobTitle)
result.append(lhs.patronalEntity == rhs.patronalEntity)
result.append(lhs.hasLivesOfIncomes == rhs.hasLivesOfIncomes)
result.append(lhs.permanentAddressContainer == rhs.permanentAddressContainer)
result.append(lhs.fiscalAddressContainer == rhs.fiscalAddressContainer)
result.append(lhs.placeOfBirth == rhs.placeOfBirth)
result.append(lhs.honorificTitle == rhs.honorificTitle)
result.append(lhs.userType == rhs.userType)
result.append(lhs.userTypeDescription == rhs.userTypeDescription)
result.append(lhs.lastVisitedCountryCode == rhs.lastVisitedCountryCode)
result.append(lhs.lastUpdate == rhs.lastUpdate)
return !result.contains(false)
}

Slickgrid sorting when using DataView and expand/collapse

I've been doing a LOT of googling, but couldn't find a way to implement this. Sorry if I missed it in my searching.
I used Example 4 adding tree functionality as a template, but I've been unable to implement column sorting while tree functionality is active.
Everything I've tried winds up in an infinite loop in the rendered version of my inline filter due to the IDs no longer being in order.
Has anyone been able to implement sorting with tree functionality or have any pointers how it can be accomplished? Is there a way to sort the parent rows and leave the parents and children together?
My filter is basically the same as the one in the example with some minor tweaks to the search.
It gets stuck looping the item.parent if since the parents and children are no longer sequential. Now all rows have children.
if (item.parent != null) {
var parent = oppLineGridData[item.parent];
while (parent) {
if (parent._collapsed) {
return false;
}
parent = oppLineGridData[parent.parent];
}
}
Full function:
function openFilter(item) {
if (specificColumn != null) {
if (searchString != "" && item[specificColumn].toLowerCase().indexOf(searchString) == -1) {
return false;
}
} else {
if (searchString != ""
&& item["accountName"].toLowerCase().indexOf(searchString) == -1
&& item["solution"].toString().toLowerCase().indexOf(searchString) == -1
&& item["Adjusted_Commitment__c"].toLowerCase().indexOf(searchString) == -1
&& item["Deal_Registration_ID__c"].toLowerCase().indexOf(searchString) == -1
&& item["lineItemValue"].toString().toLowerCase().indexOf(searchString) == -1
&& item["oppotunityName"].toLowerCase().indexOf(searchString) == -1
&& item["closeDate"].toLowerCase().indexOf(searchString) == -1
&& item["productName"].toLowerCase().indexOf(searchString) == -1
&& item["stageName"].toLowerCase().indexOf(searchString) == -1
&& item["ownerName"].toLowerCase().indexOf(searchString) == -1
&& item["accountManagerList"].toLowerCase().indexOf(searchString) == -1
&& item["accountManagerMgr2"].toLowerCase().indexOf(searchString) == -1
&& item["ProServicesEngagement"].toLowerCase().indexOf(searchString) == -1
&& item["proServicesEngagementAll"].toLowerCase().indexOf(searchString) == -1
&& item["productType"].toLowerCase().indexOf(searchString) == -1
&& item["commissionableEMName"].toLowerCase().indexOf(searchString) == -1
&& item["lastUpdated"].toLowerCase().indexOf(searchString) == -1
&& item["updatedBy"].toLowerCase().indexOf(searchString) == -1) {
return false;
}
}
if (item.parent != null) {
var parent = oppLineGridData[item.parent];
while (parent) {
if (parent._collapsed) {
return false;
}
parent = oppLineGridData[parent.parent];
}
}
return true;
}
The only answer is to disable the inlining of filters. In other words, the option inlineFilters should be set to false.
I just suffered from the same issue and I tell you this from the experience. The inlining of filters for SlickGrid won't handle complex code.
Even a for with an if inside or a inner loop was enough for it to go into infinite loop for me.

How to simplify a simple loop in Javascript?

I am now trying it out for a while and get it perfect. I am trying to simplify this for loop I created and make it actually work, without any arrays and only the most basic of basic JavaScript.
for (var x=0;x<=1;x++) {
if (secondInput == luckyNumber || secondInput == luckyNumber2 || secondInput == luckyNumber3) {
if (thirdInput == luckyNumber || thirdInput == luckyNumber2 || thirdInput == luckyNumber3) {
if (firstInput == luckyNumber || firstInput == luckyNumber2 || firstInput == luckyNumber3) {
while (firstInput !== secondInput){
while(firstInput !== thirdInput){while(secondInput !== thirdInput) {
alert('Congratulations! You got all 3 numbers correct. You\'ve won £1,000!');
}
}
}
}
}
}
Does this code make sense or am I doing something wrong? I've got the feeling that I can even leave the loop out, but it is the only way how I think it is correct.
Write a function that takes the input, compares it to the lucky numbers and returns a boolean with the result.
Call that function in your if clauses.
I don't quite understand what you are trying to do with the while loops.
You could try using this idea to help:
[1, 3, 2].sort()
(store your questions and answers in arrays, and sort both then compare. Of course, checking javascript arrays for equality is a fun new project :) )
Here you go. You said you wanted it simplified.
for (var x = 0; 1 >= x; x++) {
if (!(secondInput != luckyNumber && secondInput != luckyNumber2 && secondInput != luckyNumber3 || thirdInput != luckyNumber && thirdInput != luckyNumber2 && thirdInput != luckyNumber3 || firstInput != luckyNumber && firstInput != luckyNumber2 && firstInput != luckyNumber3)) {
while (firstInput !== secondInput) {
while (firstInput !== thirdInput) {
while (secondInput !== thirdInput) {
alert("Congratulations! You got all 3 numbers correct. You\'ve won £1,000!");
}
}
}
}
}

Linq to nHibernate - exclude elements without child elements

var locations = (from location in session.Query<Location>()
where
(location.MB_ID == 0 || location.MB_ID == null) &&
(location.hide != "Y" || location.hide == null) &&
(location.locationNameRaw != "" && location.locationNameRaw != null) &&
((location.isIPCapableText != "" && location.isIPCapableText != null) || (
(location.ISDNNumber1 != null && location.ISDNNumber1 != "") ||
(location.ISDNNumber2 != null && location.ISDNNumber2 != "") ||
(location.ISDNNumber3 != null && location.ISDNNumber3 != "") ||
(location.ISDNNumber4 != null && location.ISDNNumber4 != "") ||
(location.ISDNNumber5 != null && location.ISDNNumber5 != "") ||
(location.ISDNNumber6 != null && location.ISDNNumber6 != "")
))
&& (location.privateRoom == "N" || location.privateRoom == "" || location.privateRoom != null)
&& (
from lll in session.Query<LocationLonLat>()
where
location.locationID == lll.locationId
select lll.locationId
).Any()
&& (location.LastUpdatedTime > lastUpdateTime)
&& location.LocationTimes.Count() > 0
/*&& (
from lt in session.Query<LocationTimes>()
where
location.locationID == lt.LID
select lt.LID
).Any()*/
select location
)
.ToList();
There is a relationship between Location (1) and LocationTimes (many), and I only want to return a dataset of locations that have at least one LocationTime record.
I tried a couple of things...
When I add the line:
&& location.LocationTimes.Count() > 0
or if I add the line:
&& (
from lt in session.Query<LocationTimes>()
where
location.locationID == lt.LID
select lt.LID
).Any()
The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.
I suspect that this may because of the size of the dataset or something...
Is there a better way of doing this? Like with a 'left outer join' or something?
I think a simple join should do it.
from locationTime in Query<LocationTime>()
join location in Query<Location>() on locationTime.Location.LocationId equals location.LocationId
join locationLat in Query<LocationLat>() on location.LocationLat.LocationLatId equals locationLat.LocationLatId
where ...
select location;

Silly question about how you format long if statements

On long if statements where they take up more than one line, do you put the conditions like AND or OR on a new line like this:
if (something
&& something else)
Or like this:
if (something &&
something else)
For complex conditions, consider extracting it into a function or a variable:
if (complexCondition(foo)) { ..
As a bonus, the name of the function or variable can be used to communicate what the condition means. This makes your code easier to read.
I typically do it the second way, since I can line up the statements. However, either way is fine when you're writing code, as long as you're consistent.
I prefer a rendition of the first. My reasoning is that deleting a condition via cut/paste/comment for any testing purposes is easier. It's a lot easier to comment out a line than it is to delete the and from the line above and comment out a line. This is more when I'm doing where clauses in SQL than in an if statement in any other given language, but is similar.
Given my druthers, I'd avoid long if tests in the first place. I'd rather do something like:
bool fTest1 = A == B ;
bool fTest2 = C ;
bool fTest3 = f(1,2,3) ;
bool fSuccess = ( fTest1 | ftest2 ) & fTest3 ;
if ( fSuccess )
...
Otherwise something like this:
if ( A == B
&& ( C == D
|| E == F
)
&& Z > Y
) {
...
}
else
{
...
}
YMMV, of course.
The former is far easier to debug, test, log, etc.
I usually format using the IDE formatter and then rearrange a bit to make it look beautiful.
I'm working in VSC and recently managed to not only write, but make readable very long conditions in nested if statements. Just use brackets and new lines like this. It should make automatic indentations:
foreach ($panstwa as $key => $value) {
if (is_object($value)) {
if (
(
($value->checkbox1 === true) && (is_string($value->panstwoZListy)) && ($value->panstwoZListy !== 'none') && ($value->panstwo === '') && ($value->panstwoZListy !== '')
) ||
(
(
($value->checkbox2 === true &&
($value->checkbox2_1 === true || $value->checkbox2_2 === true || $value->checkbox2_3 === true || $value->checkbox2_4 === true || $value->checkbox2_5 === true || $value->checkbox2_6 === true)
) ||
($value->checkbox3 === true &&
($value->checkbox3_1 === true || $value->checkbox3_2 === true)
) ||
($value->checkbox4 === true &&
(
(
($value->checkbox4_1 === true || $value->checkbox4_2 === true || $value->checkbox4_3 === true || $value->checkbox4_4 === true || $value->checkbox4_5 === true || $value->checkbox4_6 === true || $value->checkbox4_7 === true) && ($value->checkbox4_8 === false)
) ||
(
($value->checkbox4_1 === false && $value->checkbox4_2 === false && $value->checkbox4_3 === false && $value->checkbox4_4 === false && $value->checkbox4_5 === false && $value->checkbox4_6 === false && $value->checkbox4_7 === false) && ($value->checkbox4_8 === true) && (sprawdzRegexTextInput($value->prawnieUzasadnionyInteres)) && (is_object($value->dokumentacjaOceny) || is_string($value->dokumentacjaOceny))
)
)
)
) &&
(is_string($value->panstwo)) && ($value->panstwoZListy === 'none') && ($value->panstwo !== '') && (sprawdzRegexTextInput($value->panstwo)
)
) &&
((is_int($value->panstwoid) && is_numeric($value->panstwoid)) || (is_bool($value->panstwoid) && $value->panstwoid === false)) &&
(is_bool($value->zmiana))
) {
echo "ok";
//nie robię nic
} else {
$flagaPanstwa = false;
}
} else {
$flagaPanstwa = false;
}
}

Resources