Related
I would create free app for muslims which will notify pray time ( namaz time).
I dont know quite a few how to measure pray time (Namaz time).
I saw some example code, but these codes were wrong for My Country (UZBEKISTAN ).
Please, show or explain how to measure Namaz time for Uzbekistan or any country depending on geolocation.
import 'dart:collection';
import 'dart:math' as math;
import 'dart:core';
void main() {
double latitude = 41.311081;
double longitude = 69.240562;
double timezone = 5;
// Test Prayer times here
// PrayTime prayers = new PrayTime();
PrayerTime prayers = new PrayerTime();
prayers.setTimeFormat(prayers.getTime24());
prayers.setCalcMethod(prayers.getISNA());
prayers.setAsrJuristic(prayers.getHanafi());
prayers.setAdjustHighLats(prayers.getAdjustHighLats());
List<int>offsets = [0, 0, 0, 0, 0, 0, 0]; // {Fajr,Sunrise,Dhuhr,Asr,Sunset,Maghrib,Isha}
prayers.tune(offsets);
List<String> prayerTimes = prayers.getPrayerTimes(DateTime.now(),
latitude, longitude, timezone);
List<String> prayerNames = prayers.getTimeNames();
for (int i = 0; i < prayerTimes.length; i++) {
print(prayerNames[i] + " - " + prayerTimes[i]);
}
}
class PrayerTime {
// ---------------------- Global Variables --------------------
int _calcMethod; // caculation method
int _asrJuristic; // Juristic method for Asr
int _dhuhrMinutes; // minutes after mid-day for Dhuhr
int _adjustHighLats; // adjusting method for higher latitudes
int _timeFormat; // time format
double _lat; // latitude
double _lng; // longitude
double _timeZone; // time-zone
double _jDate; // Julian date
// ------------------------------------------------------------
// Calculation Methods
int _jafri; // Ithna Ashari
int _karachi; // University of Islamic Sciences, Karachi
int _iSNA; // Islamic Society of North America (ISNA)
int _mWL; // Muslim World League (MWL)
int _makkah; // Umm al-Qura, Makkah
int _egypt; // Egyptian General Authority of Survey
int _custom; // Custom Setting
int _tehran; // Institute of Geophysics, University of Tehran
// Juristic Methods
int _shaffi; // Shafii (standard)
int _hanafi; // Hanafi
// Adjusting Methods for Higher Latitudes
int _none; // No adjustment
int _midNight; // middle of night
int _oneSeventh; // 1/7th of night
int _angleBased; // angle/60th of night
// Time Formats
int _time24; // 24-hour format
int _time12; // 12-hour format
int _time12Ns; // 12-hour format with no suffix
int _floating; // floating point number
// Time Names
List<String> _timeNames;
String _invalidTime; // The string used for invalid times
// --------------------- Technical Settings --------------------
int _numIterations;
// ------------------- Calc Method Parameters --------------------
Map<int, List<double>> _methodParams;
/*
* this.methodParams[methodNum] = new Array(fa, ms, mv, is, iv);
*
* fa : fajr angle ms : maghrib selector (0 = angle; 1 = minutes after
* sunset) mv : maghrib parameter value (in angle or minutes) is : isha
* selector (0 = angle; 1 = minutes after maghrib) iv : isha parameter value
* (in angle or minutes)
*/
List<double> _prayerTimesCurrent;
List<int> _offsets;
PrayerTime() {
this.setCalcMethod(0);
this.setAsrJuristic(0);
this.setDhuhrMinutes(0);
this.setAdjustHighLats(1);
this.setTimeFormat(0);
// Calculation Methods
this.setJafari(0); // Ithna Ashari
this.setKarachi(1); // University of Islamic Sciences, Karachi
this.setISNA(2); // Islamic Society of North America (ISNA)
this.setMWL(3); // Muslim World League (MWL)
this.setMakkah(4); // Umm al-Qura, Makkah
this.setEgypt(5); // Egyptian General Authority of Survey
this.setTehran(6); // Institute of Geophysics, University of Tehran
this.setCustom(7); // Custom Setting
// Juristic Methods
this.setShafii(0); // Shafii (standard)
this.setHanafi(1); // Hanafi
// Adjusting Methods for Higher Latitudes
this.setNone(0); // No adjustment
this.setMidNight(1); // middle of night
this.setOneSeventh(2); // 1/7th of night
this.setAngleBased(3); // angle/60th of night
// Time Formats
this.setTime24(0); // 24-hour format
this.setTime12(1); // 12-hour format
this.setTime12NS(2); // 12-hour format with no suffix
this.setFloating(3); // floating point number
// Time Names
_timeNames = new List<String>();
_timeNames.add("Fajr");
_timeNames.add("Sunrise");
_timeNames.add("Dhuhr");
_timeNames.add("Asr");
_timeNames.add("Sunset");
_timeNames.add("Maghrib");
_timeNames.add("Isha");
_invalidTime = "-----"; // The string used for invalid times
// --------------------- Technical Settings --------------------
this.setNumIterations(1); // number of iterations needed to compute
// times
// ------------------- Calc Method Parameters --------------------
// Tuning offsets {fajr, sunrise, dhuhr, asr, sunset, maghrib, isha}
_offsets = new List<int>(7);
_offsets[0] = 0;
_offsets[1] = 0;
_offsets[2] = 0;
_offsets[3] = 0;
_offsets[4] = 0;
_offsets[5] = 0;
_offsets[6] = 0;
/*
*
* fa : fajr angle ms : maghrib selector (0 = angle; 1 = minutes after
* sunset) mv : maghrib parameter value (in angle or minutes) is : isha
* selector (0 = angle; 1 = minutes after maghrib) iv : isha parameter
* value (in angle or minutes)
*/
_methodParams = new HashMap<int, List<double>>();
// Jafari
List<double> _jValues = [16, 0, 4, 0, 14];
_methodParams[this.getJafari()] = _jValues;
// Karachi
List<double> _kValues = [18, 1, 0, 0, 18];
_methodParams[this.getKarachi()] = _kValues;
// ISNA
List<double> _iValues = [15, 1, 0, 0, 15];
_methodParams[this.getISNA()] = _iValues;
// MWL
List<double> _mwValues = [18, 1, 0, 0, 17];
_methodParams[this.getMWL()] = _mwValues;
// Makkah
List<double> _mkValues = [18.5, 1, 0, 1, 90];
_methodParams[this.getMakkah()] = _mkValues;
// Egypt
List<double> _eValues = [19.5, 1, 0, 0, 17.5];
_methodParams[this.getEgypt()] = _eValues;
// Tehran
List<double> _tValues = [17.7, 0, 4.5, 0, 14];
_methodParams[this.getTehran()] = _tValues;
// Custom
List<double> _cValues = [18, 1, 0, 0, 17];
_methodParams[this.getCustom()] = _cValues;
}
// ---------------------- Trigonometric Functions -----------------------
// range reduce angle in degrees.
double _fixAngle(double a) {
a = a - (360 * ((a / 360.0).floor()));
a = a < 0 ? (a + 360) : a;
return a;
}
//range reduce hours to 0..23
double _fixHour(double a) {
a = a - 24.0 * (a / 24.0).floor();
a = a < 0 ? (a + 24) : a;
return a;
}
// radian to degree
double _radiansToDegrees(double alpha) {
return ((alpha * 180.0) / math.pi);
}
// deree to radian
double _degreesToRadians(double alpha) {
return ((alpha * math.pi) / 180.0);
}
// degree sin
double _dsin(double d) {
return (math.sin(_degreesToRadians(d)));
}
// degree cos
double _dcos(double d) {
return (math.cos(_degreesToRadians(d)));
}
// degree tan
double _dtan(double d) {
return (math.tan(_degreesToRadians(d)));
}
// degree arcsin
double _darcsin(double x) {
double val = math.asin(x);
return _radiansToDegrees(val);
}
// degree arccos
double darccos(double x) {
double val = math.acos(x);
return _radiansToDegrees(val);
}
// degree arctan
double _darctan(double x) {
double val = math.atan(x);
return _radiansToDegrees(val);
}
// degree arctan2
double _darctan2(double y, double x) {
double val = math.atan2(y, x);
return _radiansToDegrees(val);
}
// degree arccot
double darccot(double x) {
double val = math.atan2(1.0, x);
return _radiansToDegrees(val);
}
// ---------------------- Time-Zone Functions -----------------------
// compute local time-zone for a specific date
/* getTimeZone1() {
TimeZone timez = TimeZone.;
double hoursDiff = (timez.getRawOffset() / 1000.0) / 3600;
return hoursDiff;
}
// compute base time-zone of the system
getBaseTimeZone() {
TimeZone timez = TimeZone.getDefault();
double hoursDiff = (timez.getRawOffset() / 1000.0) / 3600;
return hoursDiff;
}
// detect daylight saving in a given date
detectDaylightSaving() {
TimeZone timez = TimeZone.UTC;
double hoursDiff = timez.getDSTSavings();
return hoursDiff;
}*/
// ---------------------- Julian Date Functions -----------------------
// calculate julian date from a calendar date
julianDate(int year, int month, int day) {
if (month <= 2) {
year -= 1;
month += 12;
}
double A = (year / 100.0).floorToDouble();
double B = 2 - A + (A / 4.0).floor();
double JD = (365.25 * (year + 4716)).floor() +
(30.6001 * (month + 1)).floor() +
day +
B -
1524.5;
return JD;
}
/*// convert a calendar date to julian date (second method)
calcJD(int year, int month, int day) {
double J1970 = 2440588.0;
Date date = new Date(year, month - 1, day);
double ms = date.getTime(); // # of milliseconds since midnight Jan 1,
// 1970
double days = (ms / (1000.0 * 60.0 * 60.0 * 24.0)).floorToDouble();
return J1970 + days - 0.5;
}*/
//
// ---------------------- Calculation Functions -----------------------
// ---------------------- Calculation Functions -----------------------
// References:
// http://www.ummah.net/astronomy/saltime
// http://aa.usno.navy.mil/faq/docs/SunApprox.html
// compute declination angle of sun and equation of time
List<double> sunPosition(double jd) {
double D = jd - 2451545;
double g = _fixAngle(357.529 + 0.98560028 * D);
double q = _fixAngle(280.459 + 0.98564736 * D);
double L = _fixAngle(q + (1.915 * _dsin(g)) + (0.020 * _dsin(2 * g)));
// double R = 1.00014 - 0.01671 * [self dcos:g] - 0.00014 * [self dcos:
// (2*g)];
double e = 23.439 - (0.00000036 * D);
double d = _darcsin(_dsin(e) * _dsin(L));
double RA = (_darctan2((_dcos(e) * _dsin(L)), (_dcos(L)))) / 15.0;
RA = _fixHour(RA);
double EqT = q / 15.0 - RA;
List<double> sPosition = new List(2);
sPosition[0] = d;
sPosition[1] = EqT;
return sPosition;
}
// compute equation of time
double equationOfTime(double jd) {
double eq = sunPosition(jd)[1];
return eq;
}
// compute declination angle of sun
double sunDeclination(double jd) {
double d = sunPosition(jd)[0];
return d;
}
// compute mid-day (Dhuhr, Zawal) time
double computeMidDay(double t) {
double T = equationOfTime(this.getJDate() + t);
double Z = _fixHour(12 - T);
return Z;
}
// compute time for a given angle G
double computeTime(double G, double t) {
double D = sunDeclination(this.getJDate() + t);
double Z = computeMidDay(t);
double Beg = -_dsin(G) - _dsin(D) * _dsin(this.getLat());
double Mid = _dcos(D) * _dcos(this.getLat());
double V = darccos(Beg / Mid) / 15.0;
return Z + (G > 90 ? -V : V);
}
// compute the time of Asr
// Shafii: step=1, Hanafi: step=2
double computeAsr(double step, double t) {
double D = sunDeclination(this.getJDate() + t);
double G = -darccot(step + _dtan((this.getLat() - D).abs()));
return computeTime(G, t);
}
// ---------------------- Misc Functions -----------------------
// compute the difference between two times
double timeDiff(double time1, double time2) {
return _fixHour(time2 - time1);
}
// -------------------- Interface Functions --------------------
// return prayer times for a given date
List<String> getDatePrayerTimes(int year, int month, int day, double latitude,
double longitude, double tZone) {
this.setLat(latitude);
this.setLng(longitude);
this.setTimeZone(tZone);
this.setJDate(julianDate(year, month, day));
double lonDiff = longitude / (15.0 * 24.0);
this.setJDate(this.getJDate() - lonDiff);
return computeDayTimes();
}
// return prayer times for a given date
List<String> getPrayerTimes(
DateTime date, double latitude, double longitude, double tZone) {
int year = date.year;
int month = date.month;
int day = date.day;
return getDatePrayerTimes(year, month, day, latitude, longitude, tZone);
}
// set custom values for calculation parameters
void setCustomParams(List<double> params) {
for (int i = 0; i < 5; i++) {
if (params[i] == null) {
params[i] = _methodParams[this._calcMethod][i];
_methodParams[this.getCustom()] = params;
} else {
_methodParams[this.getCustom()][i] = params[i];
}
}
this.setCalcMethod(this.getCustom());
}
// set the angle for calculating Fajr
void setFajrAngle(double angle) {
List<double> params = [angle, -1, -1, -1, -1];
setCustomParams(params);
}
// set the angle for calculating Maghrib
void setMaghribAngle(double angle) {
List<double> params = [-1, 0, angle, -1, -1];
setCustomParams(params);
}
// set the angle for calculating Isha
void setIshaAngle(double angle) {
List<double> params = [-1, -1, -1, 0, angle];
setCustomParams(params);
}
// set the minutes after Sunset for calculating Maghrib
void setMaghribMinutes(double minutes) {
List<double> params = [-1, 1, minutes, -1, -1];
setCustomParams(params);
}
// set the minutes after Maghrib for calculating Isha
void setIshaMinutes(double minutes) {
List<double> params = [-1, -1, -1, 1, minutes];
setCustomParams(params);
}
// convert double hours to 24h format
String floatToTime24(double time) {
String result;
if (time == double.nan) {
return _invalidTime;
}
time = _fixHour(time + 0.5 / 60.0); // add 0.5 minutes to round
int hours = time.floor();
double minutes = ((time - hours) * 60.0).floorToDouble();
if ((hours >= 0 && hours <= 9) && (minutes >= 0 && minutes <= 9)) {
result = "0" + hours.toString() + ":0" + (minutes).round().toString();
} else if ((hours >= 0 && hours <= 9)) {
result = "0" + hours.toString() + ":" + (minutes).round().toString();
} else if ((minutes >= 0 && minutes <= 9)) {
result = hours.toString() + ":0" + (minutes).round().toString();
} else {
result = hours.toString() + ":" + (minutes).round().toString();
}
return result;
}
// convert double hours to 12h format
String floatToTime12(double time, bool noSuffix) {
if (time == double.nan) {
return _invalidTime;
}
time = _fixHour(time + 0.5 / 60); // add 0.5 minutes to round
int hours = (time).floor();
double minutes = ((time - hours) * 60).floorToDouble();
String suffix, result;
if (hours >= 12) {
suffix = "PM";
} else {
suffix = "AM";
}
hours = ((((hours + 12) - 1) % (12)) + 1);
/*hours = (hours + 12) - 1;
int hrs = (int) hours % 12;
hrs += 1;*/
if (noSuffix == false) {
if ((hours >= 0 && hours <= 9) && (minutes >= 0 && minutes <= 9)) {
result = "0" +
hours.toString() +
":0" +
(minutes).round().toString() +
" " +
suffix;
} else if ((hours >= 0 && hours <= 9)) {
result = "0" +
hours.toString() +
":" +
(minutes).round().toString() +
" " +
suffix;
} else if ((minutes >= 0 && minutes <= 9)) {
result = hours.toString() +
":0" +
(minutes).round().toString() +
" " +
suffix;
} else {
result = hours.toString() +
":" +
(minutes).round().toString() +
" " +
suffix;
}
} else {
if ((hours >= 0 && hours <= 9) && (minutes >= 0 && minutes <= 9)) {
result = "0" + hours.toString() + ":0" + (minutes).round().toString();
} else if ((hours >= 0 && hours <= 9)) {
result = "0" + hours.toString() + ":" + (minutes).round().toString();
} else if ((minutes >= 0 && minutes <= 9)) {
result = hours.toString() + ":0" + (minutes).round().toString();
} else {
result = hours.toString() + ":" + (minutes).round().toString();
}
}
return result;
}
// convert double hours to 12h format with no suffix
String floatToTime12NS(double time) {
return floatToTime12(time, true);
}
// ---------------------- Compute Prayer Times -----------------------
// compute prayer times at given julian date
List<double> computeTimes(List<double> times) {
List<double> t = dayPortion(times);
double Fajr =
this.computeTime(180 - _methodParams[this.getCalcMethod()][0], t[0]);
double Sunrise = this.computeTime(180 - 0.833, t[1]);
double Dhuhr = this.computeMidDay(t[2]);
double Asr = this.computeAsr((1 + this.getAsrJuristic()).toDouble(), t[3]);
double Sunset = this.computeTime(0.833, t[4]);
double Maghrib =
this.computeTime(_methodParams[this.getCalcMethod()][2], t[5]);
double Isha =
this.computeTime(_methodParams[this.getCalcMethod()][4], t[6]);
List<double> CTimes = [Fajr, Sunrise, Dhuhr, Asr, Sunset, Maghrib, Isha];
return CTimes;
}
// compute prayer times at given julian date
List<String> computeDayTimes() {
List<double> times = [5, 6, 12, 13, 18, 18, 18]; // default times
for (int i = 1; i <= this.getNumIterations(); i++) {
times = computeTimes(times);
}
times = adjustTimes(times);
times = tuneTimes(times);
return adjustTimesFormat(times);
}
// adjust times in a prayer time array
List<double> adjustTimes(List<double> times) {
for (int i = 0; i < times.length; i++) {
times[i] += this.getTimeZone() - this.getLng() / 15;
}
times[2] += this.getDhuhrMinutes() / 60; // Dhuhr
if (_methodParams[this.getCalcMethod()][1] == 1) {
times[5] = times[4] + _methodParams[this.getCalcMethod()][2] / 60;
}
if (_methodParams[this.getCalcMethod()][3] == 1) {
times[6] = times[5] + _methodParams[this.getCalcMethod()][4] / 60;
}
if (this.getAdjustHighLats() != this.getNone()) {
times = adjustHighLatTimes(times);
}
return times;
}
// convert times array to given time format
List<String> adjustTimesFormat(List<double> times) {
List<String> result = new List<String>();
if (this.getTimeFormat() == this.getFloating()) {
for (double time in times) {
result.add(time.toString());
}
return result;
}
for (int i = 0; i < 7; i++) {
if (this.getTimeFormat() == this.getTime12()) {
result.add(floatToTime12(times[i], false));
} else if (this.getTimeFormat() == this.getTime12NS()) {
result.add(floatToTime12(times[i], true));
} else {
result.add(floatToTime24(times[i]));
}
}
return result;
}
// adjust Fajr, Isha and Maghrib for locations in higher latitudes
List<double> adjustHighLatTimes(List<double> times) {
double nightTime = timeDiff(times[4], times[1]); // sunset to sunrise
// Adjust Fajr
double FajrDiff =
nightPortion(_methodParams[this.getCalcMethod()][0]) * nightTime;
if (times[0] == double.nan || timeDiff(times[0], times[1]) > FajrDiff) {
times[0] = times[1] - FajrDiff;
}
// Adjust Isha
double IshaAngle = (_methodParams[this.getCalcMethod()][3] == 0)
? _methodParams[this.getCalcMethod()][4]
: 18;
double IshaDiff = this.nightPortion(IshaAngle) * nightTime;
if (times[6] == double.nan ||
this.timeDiff(times[4], times[6]) > IshaDiff) {
times[6] = times[4] + IshaDiff;
}
// Adjust Maghrib
double MaghribAngle = (_methodParams[this.getCalcMethod()][1] == 0)
? _methodParams[(this.getCalcMethod())][2]
: 4;
double MaghribDiff = nightPortion(MaghribAngle) * nightTime;
if (times[5] == double.nan ||
this.timeDiff(times[4], times[5]) > MaghribDiff) {
times[5] = times[4] + MaghribDiff;
}
return times;
}
// the night portion used for adjusting times in higher latitudes
double nightPortion(double angle) {
double calc = 0;
if (_adjustHighLats == _angleBased)
calc = (angle) / 60.0;
else if (_adjustHighLats == _midNight)
calc = 0.5;
else if (_adjustHighLats == _oneSeventh) calc = 0.14286;
return calc;
}
// convert hours to day portions
List<double> dayPortion(List<double> times) {
for (int i = 0; i < 7; i++) {
times[i] /= 24;
}
return times;
}
// Tune timings for adjustments
// Set time offsets
void tune(List<int> offsetTimes) {
for (int i = 0; i < offsetTimes.length; i++) {
// offsetTimes length
// should be 7 in order
// of Fajr, Sunrise,
// Dhuhr, Asr, Sunset,
// Maghrib, Isha
this._offsets[i] = offsetTimes[i];
}
}
List<double> tuneTimes(List<double> times) {
for (int i = 0; i < times.length; i++) {
times[i] = times[i] + this._offsets[i] / 60.0;
}
return times;
}
int getCalcMethod() {
return _calcMethod;
}
void setCalcMethod(int calcMethod) {
_calcMethod = calcMethod;
}
int getAsrJuristic() {
return _asrJuristic;
}
void setAsrJuristic(int asrJuristic) {
_asrJuristic = asrJuristic;
}
int getDhuhrMinutes() {
return _dhuhrMinutes;
}
void setDhuhrMinutes(int dhuhrMinutes) {
_dhuhrMinutes = dhuhrMinutes;
}
int getAdjustHighLats() {
return _adjustHighLats;
}
void setAdjustHighLats(int adjustHighLats) {
_adjustHighLats = adjustHighLats;
}
int getTimeFormat() {
return _timeFormat;
}
setTimeFormat(int timeFormat) {
_timeFormat = timeFormat;
}
double getLat() {
return _lat;
}
void setLat(double lat) {
_lat = lat;
}
double getLng() {
return _lng;
}
void setLng(double lng) {
_lng = lng;
}
double getTimeZone() {
return _timeZone;
}
void setTimeZone(double timeZone) {
_timeZone = timeZone;
}
double getJDate() {
return _jDate;
}
void setJDate(double jDate) {
_jDate = jDate;
}
int getJafari() {
return _jafri;
}
void setJafari(int jafari) {
_jafri = jafari;
}
int getKarachi() {
return _karachi;
}
void setKarachi(int karachi) {
_karachi = karachi;
}
int getISNA() {
return _iSNA;
}
void setISNA(int iSNA) {
_iSNA = iSNA;
}
int getMWL() {
return _mWL;
}
void setMWL(int mWL) {
_mWL = mWL;
}
int getMakkah() {
return _makkah;
}
void setMakkah(int makkah) {
_makkah = makkah;
}
int getEgypt() {
return _egypt;
}
void setEgypt(int egypt) {
_egypt = egypt;
}
int getCustom() {
return _custom;
}
void setCustom(int custom) {
_custom = custom;
}
int getTehran() {
return _tehran;
}
void setTehran(int tehran) {
_tehran = tehran;
}
int getShafii() {
return _shaffi;
}
void setShafii(int shafii) {
_shaffi = shafii;
}
int getHanafi() {
return _hanafi;
}
void setHanafi(int hanafi) {
_hanafi = hanafi;
}
int getNone() {
return _none;
}
void setNone(int none) {
_none = none;
}
int getMidNight() {
return _midNight;
}
void setMidNight(int midNight) {
_midNight = midNight;
}
int getOneSeventh() {
return _oneSeventh;
}
void setOneSeventh(int oneSeventh) {
_oneSeventh = oneSeventh;
}
int getAngleBased() {
return _angleBased;
}
void setAngleBased(int angleBased) {
_angleBased = angleBased;
}
int getTime24() {
return _time24;
}
void setTime24(int time24) {
_time24 = time24;
}
int getTime12() {
return _time12;
}
void setTime12(int time12) {
_time12 = time12;
}
int getTime12NS() {
return _time12Ns;
}
void setTime12NS(int time12ns) {
_time12Ns = time12ns;
}
int getFloating() {
return _floating;
}
void setFloating(int floating) {
_floating = floating;
}
int getNumIterations() {
return _numIterations;
}
void setNumIterations(int numIterations) {
_numIterations = numIterations;
}
List<String> getTimeNames() {
return _timeNames;
}
}```
I wrote this code on Processing 3.3.7, it creates a ball that bounces around.
Ball b;
int n = 0;
void setup() {
size(600, 400);
b = new BallBuilder()
.buildRadius(20)
.buildXSpeed(5)
.buildYSpeed(5)
.buildYAcceleration(1)
.toBall();
}
void draw() {
background(0);
n++;
print("n: " + n + " | ");
print("xSpeed: " + b.getXSpeed() + " | ");
println("ySpeed: " + b.getYSpeed());
b.display();
b.move();
}
There is also a Ball class, which has these methods:
void display() {
fill(255);
stroke(255);
ellipse(xPosition, yPosition, radius * 2, radius * 2);
}
void move() {
this.moveX();
this.moveY();
}
private void moveX() {
for(float i = 0; i <= abs(this.xSpeed); i += abs(this.xSpeed) / 10) {
this.bounceX();
this.xPosition += this.xSpeed / 10;
}
}
private void moveY() {
for(float i = 0; i <= abs(this.ySpeed); i += abs(this.ySpeed) / 10) {
this.bounceY();
this.yPosition += this.ySpeed / 10;
}
this.ySpeed += this.yAcceleration;
}
void bounceX() {
if(!this.canMoveX()) {
this.xSpeed = -this.xSpeed;
}
}
void bounceY() {
if(!this.canMoveY()) {
this.ySpeed = -this.ySpeed;
}
}
boolean canMoveX() {
if(this.xPosition < radius || this.xPosition >= width - this.radius) {
return false;
}
return true;
}
boolean canMoveY() {
if(this.yPosition < radius || this.yPosition >= height - this.radius) {
return false;
}
return true;
}
}
And there's also a builder and two getters for the Ball(not posted here, as they're pretty straight forward). The problem is, neither the xSpeed nor the ySpeed can be set to 0, otherwise the code stops running. That means that I need to give it both speeds when instantiating and if I set the acceleration makes the speed go to 0, the program stops running (the n variable is used to count the number of times the draw() loops, when the speed hits 0, it stops increasing). What am I missing?
Have you tried debugging your code to figure out where the code differs from what you expected?
You have two loops like this:
for(float i = 0; i <= abs(this.xSpeed); i += abs(this.xSpeed) / 10) {
You might add a print statement inside these loops, like this:
println("i: " + i);
If you did this, you'd discover that i is always 0. Why is that?
Think about what happens if this.xSpeed is 0: when will this loop exit?
I have a button that basically has two functions. The aim is:
First push will blink a LED 15 times.
If someone holds the button longer than 3 seconds while the LED is blinking, it should stop and go back to the initial.
So I checked the Arduino's hold a button page and came up with this code. The problem is that I can not properly stop the blinking. The line Serial.println("DONE!!"); never works.
Where should I check if the button is held or not and should I use interrupt to end the for loop?
Here is my code:
int inPin = 2; // the pin number for input (for me a push button)
int ledPin = 9;
int current; // Current state of the button
// (LOW is pressed b/c I'm using the pullup resistors)
long millis_held; // How long the button was held (milliseconds)
long secs_held; // How long the button was held (seconds)
long prev_secs_held; // How long the button was held in the previous check
byte previous = LOW;
unsigned long firstTime; // how long since the button was first pressed
long millis_held2; // How long the button was held (milliseconds)
long secs_held2; // How long the button was held (seconds)
long prev_secs_held2; // How long the button was held in the previous check
byte previous2 = LOW;
unsigned long firstTime2; // how long since the button was first pressed
void setup() {
Serial.begin(9600); // Use serial for debugging
pinMode(ledPin, OUTPUT);
digitalWrite(inPin, INPUT); // Turn on 20k pullup resistors to simplify switch input
}
void loop() {
current = digitalRead(inPin);
// if the button state changes to pressed, remember the start time
if (current == HIGH && previous == LOW && (millis() - firstTime) > 200) {
firstTime = millis();
}
millis_held = (millis() - firstTime);
secs_held = millis_held / 1000;
// This if statement is a basic debouncing tool, the button must be pushed for at least
// 100 milliseconds in a row for it to be considered as a push.
if (millis_held > 50) {
// check if the button was released since we last checked
if (current == LOW && previous == HIGH) {
// HERE YOU WOULD ADD VARIOUS ACTIONS AND TIMES FOR YOUR OWN CODE
// ===============================================================================
//////////////////////////////////////////////////////// Button pressed Blink 15 times.
if (secs_held <= 0) {
for (int i = 0; i < 15; i++) {
ledblink(1, 750, ledPin);
current = digitalRead(inPin);
if (current == HIGH && previous == LOW && (millis() - firstTime2) > 200) {
firstTime2 = millis();
}
millis_held2 = (millis() - firstTime2);
secs_held2 = millis_held2 / 1000;
if (millis_held2 > 50) {
Serial.print("previousA ");
Serial.print(previous);
Serial.print(" currentA ");
Serial.println(current);
current = digitalRead(inPin);
if (current == HIGH && previous2 == HIGH) {
Serial.println("ALMOST! ");
Serial.println(secs_held2);
if (secs_held2 >= 2 && secs_held2 < 6) {
Serial.println("DONE!!");
}
}
}
previous2 = current;
prev_secs_held2 = secs_held2;
}
}
}
}
previous = current;
prev_secs_held = secs_held;
}
void ledblink(int times, int lengthms, int pinnum) {
for (int x = 0; x < times; x++) {
digitalWrite(pinnum, HIGH);
delay (lengthms);
digitalWrite(pinnum, LOW);
delay(lengthms);
}
}
This is how it would be done without using delay():
int inPin = 2;
int ledPin = 9;
long pressTimer;
long blinkTimer;
long blinkHalfDelay = 500; //milliseconds
int blinkCount = 0;
int blinkLimit = 15;
bool blinkFlag = false;
bool blinkLatch = true;
bool currentBtnState = false;
bool lastBtnState = false;
void setup() {
}
void loop() {
lastBtnState = currentBtnState;
currentBtnState = digitalRead(inPin);
//on rising edge, start timers
if(currentBtnState==true && lastBtnState==false)
{
pressTimer = millis();
}
//debounce activation
if(currentBtnState==true && !blinkFlag && millis()-pressTimer > 50)
{
blinkTimer = millis();
blinkCount = 0;
blinkLatch = true;
blinkFlag = true;
//functional execution would go here
}
if(currentBtnState = false || (millis()-pressTimer>3000 && currentBtnState == true))
{
blinkCount=blinkLimit;
blinkLatch = false;
}
if(blinkFlag == true)
{
if(millis()-blinkTimer > blinkHalfDelay)
{
blinkTimer = millis();
if(blinkLatch)
{
digitalWrite(pinnum, HIGH);
}
else
{
digitalWrite(pinnum, LOW);
blinkCount+=1;
}
}
if(blinkCount>blinkLimit)
{
blinkFlag = false;
digitalWrite(pinnum, LOW);
}
}
}
ps: sorry for not correcting your code directly, but it was kinda hard to read...
I'm stuck in uploading the arduino sketch to the uno board. I ran into a type error problem. I am not using the polulu wheel encoder. Please help me resolve this issue.
RobotController:14: error: 'PololuWheelEncoders2' does not name a type
RobotController.pde: In function 'void setup()':
RobotController:83: error: 'encoders' was not declared in this scope
RobotController.pde: In function 'void ReadSonar()':
RobotController:271: error: 'MID_SPEED' was not declared in this scope
RobotController.pde: In function 'int NormalizeSpeed(int)':
RobotController:340: error: 'MID_SPEED' was not declared in this scope
RobotController:343: error: 'MID_SPEED' was not declared in this scope
RobotController.pde: In function 'void SetMotors(int, int, int, int, bool, bool, bool)':
RobotController:359: error: 'encoders' was not declared in this scope
RobotController.pde: In function 'void NormalizeMotors()':
RobotController:368: error: 'MID_SPEED' was not declared in this scope
RobotController:369: error: 'encoders' was not declared in this scope
RobotController.pde: In function 'void SynchronizeMotors()':
RobotController:392: error: 'encoders' was not declared in this scope
RobotController:398: error: 'MID_SPEED' was not declared in this scope
RobotController:407: error: 'MID_SPEED' was not declared in this scope
#include <Usb.h>
#include <AndroidAccessory.h>
#include <PololuWheelEncoders2.h>
#include <Servo.h>
AndroidAccessory acc("Manufacturer", "Model", "Description", "Version", "URI", "Serial");
byte RcvMsg[5];
byte SntMsg[5];
Servo rightSideMotors;
Servo leftSideMotors;
PololuWheelEncoders2 encoders;
const int MIN_SPEED = 40;
const int MAX_SPEED = 140;
const int RIGHT_ADV_THRES = 100;
const int WHEEL_CIR = 36; //wheel circumference in cm
const int BAUD_RATE = 9600;
const int LAS_HOR_PIN = 2; //blue
const int LAS_VERT_PIN = 3; //white
const int CAM_HOR_PIN = 4;
const int CAM_VERT_PIN = 5;
const int FRONT_SONAR = 8;
const int REAR_SONAR = 9;
const int SPEED_CONT_PIN = 14;
const int DIR_CONT_PIN = 6;
int LoopCount = 0;
Servo LaserHor;
Servo CameraHor;
Servo CameraVert;
Servo LaserVert;
int RightSideAdv = 0;
long LeftSideStop = 0;
long RightSideStop = 0;
int LeftSideSpeed = 0;
int RightSideSpeed = 0;
const int DELAY = 1;
const int READ_SONAR_FREQ = 10;
const int BROADCAST_SONAR_FREQ = 10;
const int SONAR_SAMPLES = 30;
const int SONAR_TAKE_ACTION_THRESHOLD = 50;
const int SYNCH_MOTORS_FREQ = 100;
bool HeedSonar = true;
bool Synchronize = false;
bool WatchForStop = true;
bool TEST_CYCLE = false;
int TEST_COUNT = 0;
enum Commands { CmdMoveForward, CmdMoveForwardDistance, CmdMoveBackward, CmdMoveBackwardDistance, CmdSpinLeft, CmdSpinLeftDistance, CmdSpinRight, CmdSpinRightDistance, CmdStop, CmdMoveCameraVert, CmdMoveCameraHor };
enum Events { EvtFrontSonar, EvtRearSonar, EvtSonarStop, EvtDistanceStop };
void setup () {
Serial.begin(BAUD_RATE);
//LaserHor.attach(LAS_HOR_PIN);
LaserVert.attach(LAS_VERT_PIN);
CameraHor.attach(CAM_HOR_PIN);
CameraVert.attach(CAM_VERT_PIN);
//LaserHor.write(90);
LaserVert.write(90);
CameraHor.write(90);
CameraVert.write(90);
rightSideMotors.attach(SPEED_CONT_PIN);
leftSideMotors.attach(DIR_CONT_PIN);
pinMode(FRONT_SONAR, INPUT);
pinMode(REAR_SONAR, INPUT);
encoders.init(10, 11, 13, 12);
MoveForward(50, 1000);
acc.powerOn();
}
void TestCycle() {
/*Serial.println("STOPPING:");
Serial.println(LeftSideStop);
Serial.println(RightSideStop);
Serial.println(abs(encoders.getCountsLeft()) - LeftSideStop);
Serial.println(abs(encoders.getCountsRight()) - RightSideStop);*/
TEST_COUNT++;
if (TEST_COUNT == 1) {
CameraHor.write(45);
delay(150);
CameraHor.write(0);
delay(1000);
CameraHor.write(45);
delay(150);
CameraHor.write(135);
delay(150);
CameraHor.write(180);
delay(1000);
CameraHor.write(135);
delay(150);
CameraHor.write(90);
delay(150);
SpinRight(50, 180);
}
if (TEST_COUNT == 2) {
CameraVert.write(45);
delay(500);
CameraVert.write(135);
delay(500);
CameraVert.write(90);
delay(500);
MoveForward(90, 1000);
}
if (TEST_COUNT == 3) {
CameraVert.write(130);
}
}
void loop() {
if (acc.isConnected()) {
LaserVert.write(130);
ReadIncomingSignal();
if (WatchForStop) {
NormalizeMotors();
}
if (HeedSonar) {
UpdateLoopCount();
if (LoopCount % READ_SONAR_FREQ == 0) {
ReadSonar();
}
if (LoopCount % SYNCH_MOTORS_FREQ == 0) {
SynchronizeMotors();
}
delay(DELAY);
}
}
else {
LaserVert.write(90);
}
}
void SendToAndroid(byte signal, unsigned long value) {
//Serial.print("Sending: ");
//Serial.println(signal);
SntMsg[0] = signal;
SntMsg[1] = value >> 24;
SntMsg[2] = value >> 16;
SntMsg[3] = value >> 8;
SntMsg[4] = value;
acc.write(SntMsg, 5);
}
void ReadIncomingSignal() {
int len = acc.read(RcvMsg, 9, 1);
while (len > 0) {
switch(RcvMsg[0]){
case CmdMoveForward:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveForward(speed);
break;
}
case CmdMoveForwardDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
MoveForward(speed, distance);
break;
}
case CmdMoveBackward:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveBackward(speed);
break;
}
case CmdMoveBackwardDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
MoveBackward(speed, distance);
break;
}
case CmdSpinLeft:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
SpinLeft(speed);
break;
}
case CmdSpinLeftDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
SpinLeft(speed, distance);
break;
}
case CmdSpinRight:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
SpinRight(speed);
break;
}
case CmdSpinRightDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
SpinRight(speed, distance);
break;
}
case CmdStop:
{
Stop();
break;
}
case CmdMoveCameraVert:
{
int degrees = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveCameraVert(degrees);
break;
}
case CmdMoveCameraHor:
{
int degrees = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveCameraHor(degrees);
break;
}
}
len = acc.read(RcvMsg, 9, 1);
}
}
int getIntFromBytes(byte b1, byte b2, byte b3, byte b4)
{
int value = 0;
value += b1;
value <<= 8;
value += b2;
value <<= 8;
value += b3;
value <<= 8;
value += b4;
return value;
}
void UpdateLoopCount() {
LoopCount = (LoopCount % 1000) + 1;
}
void ReadSonar()
{
unsigned long frontSum = 0;
unsigned long rearSum = 0;
for (int i = 0; i < SONAR_SAMPLES; i++) {
unsigned long frontDuration = pulseIn(FRONT_SONAR, HIGH);
unsigned long rearDuration = pulseIn(REAR_SONAR, HIGH);
frontSum += frontDuration / 147.0 * 2.54;
rearSum += rearDuration / 147.0 * 2.54;
}
unsigned long frontAvg = frontSum / SONAR_SAMPLES;
unsigned long rearAvg = rearSum / SONAR_SAMPLES;
bool forward = LeftSideSpeed > MID_SPEED || RightSideSpeed > MID_SPEED;
if (HeedSonar && ((forward && frontAvg <= SONAR_TAKE_ACTION_THRESHOLD) || (!forward && rearAvg <= SONAR_TAKE_ACTION_THRESHOLD))) {
Stop();
}
Serial.println(LoopCount);
Serial.println(frontAvg);
if (LoopCount % BROADCAST_SONAR_FREQ == 0) {
SendToAndroid(EvtFrontSonar, frontAvg);
SendToAndroid(EvtRearSonar, rearAvg);
}
}
void MoveForward(int speed) {
SetMotors(speed, speed, 0, 0, true, true, false);
}
void MoveForward(int speed, int cms) {
SetMotors(speed, speed, cms, cms, true, true, true);
}
void MoveBackward(int speed) {
SetMotors(-speed, -speed, 0, 0, true, true, false);
}
void MoveBackward(int speed, int cms) {
SetMotors(-speed, -speed, cms, cms, true, true, true);
}
void SpinLeft(int speed) {
SetMotors(-speed, speed, 0, 0, true, false, false);
}
void SpinLeft(int speed, int degrees) {
int cms = (degrees / 3.0);
int extra = ((cms - 30) / 30.0);
cms += extra;
SetMotors(-speed, speed, cms, cms, true, false, true);
}
void SpinRight(int speed) {
SetMotors(speed, -speed, 0, 0, true, false, false);
}
void SpinRight(int speed, int degrees) {
int cms = (degrees / 3.0);
int extra = ((cms - 30) / 30.0) * 2.0;
cms += extra;
SetMotors(speed, -speed, cms, cms, true, false, true);
}
void MoveCameraVert(int degrees) {
CameraVert.write(degrees);
}
void MoveCameraHor(int degrees) {
CameraHor.write(degrees);
}
void Stop() {
SetMotors(0, 0, 0, 0, false, true, true);
if (TEST_CYCLE) {
TestCycle();
}
}
int NormalizeSpeed(int speedAsPercent) {
if (speedAsPercent == 0) {
return MID_SPEED;
}
else {
return (int)(MID_SPEED + ((MAX_SPEED - MID_SPEED) * (speedAsPercent / 100.0)));
}
}
long NormalizeDistance(int cms) {
return (long)((cms * 3200.0) / WHEEL_CIR); //64 counts per rev, 50:1 ratio = 64 * 50 = 3200
}
void SetMotors(int leftSpeed, int rightSpeed, int leftStop, int rightStop, bool synchronize, bool heedSonar, bool watchForStop) {
LeftSideSpeed = NormalizeSpeed(leftSpeed);
RightSideSpeed = NormalizeSpeed(rightSpeed);
LeftSideStop = NormalizeDistance(leftStop);
RightSideStop = NormalizeDistance(rightStop);
leftSideMotors.write(LeftSideSpeed);
rightSideMotors.write(RightSideSpeed);
encoders.getCountsAndResetRight();
encoders.getCountsAndResetLeft();
Synchronize = synchronize;
HeedSonar = heedSonar;
WatchForStop = watchForStop;
RightSideAdv = 0;
}
void NormalizeMotors() {
if (LeftSideSpeed != MID_SPEED || RightSideSpeed != MID_SPEED) {
long left = abs(encoders.getCountsLeft());
long right = abs(encoders.getCountsRight());
bool stopLeft = left >= LeftSideStop;
bool stopRight = right >= RightSideStop;
if (stopLeft && stopRight) {
Stop();
}
else {
if (stopLeft) {
LeftSideSpeed = 0;
leftSideMotors.write(MID_SPEED);
}
if (stopRight) {
RightSideSpeed = 0;
rightSideMotors.write(MID_SPEED);
}
}
}
}
void SynchronizeMotors() {
if (Synchronize) {
long left = abs(encoders.getCountsLeft());
long right = abs(encoders.getCountsRight());
int newRightAdv = right - left;
if (abs(newRightAdv) > RIGHT_ADV_THRES && abs(newRightAdv) > abs(RightSideAdv)) {
if (newRightAdv > 0) {
//Serial.println("DOWN");
if (RightSideSpeed < MID_SPEED) {
RightSideSpeed += 1;
}
else {
RightSideSpeed -= 1;
}
}
else {
//Serial.println("UP");
if (RightSideSpeed < MID_SPEED) {
RightSideSpeed -= 1;
}
else {
RightSideSpeed += 1;
}
}
rightSideMotors.write(RightSideSpeed);
}
RightSideAdv = newRightAdv;
}
}
thanks in advance!
Do you not need the Poloulu wheel encoders? In line 12, you create a variable named "encoders" which is set to type = PololuWheelEncoders2. The error is telling you that this is not a valid type for a variable.
I am trying to group segments of the XBee output into a variable that joins them. I am using Processing to code and compile. The issue I am having is that the output (println) is skipping every other byte (maybe that's the wrong term). So XBee output for i = 4 though 11 should look like this:
0,19,162,0,64,121,230,206 (this is the XBee address converted from hex).
But the println shows this:
19,0,121,206,125,1,0,3 (which starts getting into other segments of the output).
Later, I tried a different route by using an array. It still skips every other entry and I've found that it has to do with my check for i == 126. Is there an alternate way of doing a check like this?
Substitute this draw section for the one below. It's simpler to follow. This was a test with same results...
void draw() {
if (myPort.available() > 21) {
int[] XBeeAddr = new int[22];
for (int i=0; i<22; i++) {
XBeeAddr[i] = myPort.read();
if (myPort.read == 126) {
i=0;
}
println(XBeeAddr[0] + "," + XBeeAddr[1] + "," + XBeeAddr[2]);
}
}
Original code
import processing.serial.*;
import de.bezier.data.sql.*; // For SQLite database
SQLite db; // For SQLite database
Serial myPort;
void setup() {
println(Serial.list());
myPort = new Serial(this, Serial.list()[0],9600);
// For SQLite database...
size( 100, 100 );
db = new SQLite( this, "test.db" ); // Open database file
if ( db.connect() ) {
String[] tableNames = db.getTableNames();
db.query( "SELECT * FROM %s", tableNames[0] );
while (db.next()) {
TableOne t = new TableOne();
db.setFromRow( t );
println( t );
}
}
}
// For SQLite database
class TableOne {
public String fieldOne;
public int fieldTwo;
public String toString () {
return String.format("fieldOne: %s fieldTwo: %d", fieldOne, fieldTwo);
}
}
void draw() {
if (myPort.available() > 21) {
int XBeeAddr1 = 0;
int XBeeAddr2 = 0;
int XBeeAddr3 = 0;
int XBeeAddr4 = 0;
int XBeeAddr5 = 0;
int XBeeAddr6 = 0;
int XBeeAddr7 = 0;
int XBeeAddr8 = 0;
for (int i=0; i<22; i++) {
int inByte = myPort.read();
if (inByte == 126) {
i=0; // This resets the counter if XBee data was incomplete on the last run.
}
if (i == 4) {
XBeeAddr1 = myPort.read();
}
if (i == 5) {
XBeeAddr2 = myPort.read();
}
if (i == 6) {
XBeeAddr3 = myPort.read();
}
if (i == 7) {
XBeeAddr4 = myPort.read();
}
if (i == 8) {
XBeeAddr5 = myPort.read();
}
if (i == 9) {
XBeeAddr6 = myPort.read();
}
if (i == 10) {
XBeeAddr7 = myPort.read();
}
if (i == 11) {
XBeeAddr8 = myPort.read();
}
String XBeeAddrAll = XBeeAddr1 + "," +
XBeeAddr2 + "," +
XBeeAddr3 + "," +
XBeeAddr4 + "," +
XBeeAddr5 + "," +
XBeeAddr6 + "," +
XBeeAddr7 + "," +
XBeeAddr8;
println(XBeeAddrAll);
}
}
}
It was fixed by changing myPort.read == 126 to if XBeeAddr[0] != 126, break. Then later I did an if XBeeAddr[0] == 126 println.